P1558 色板游戏 线段树

  

题目背景

阿宝上学了,今天老师拿来了一块很长的涂色板。

题目描述

色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格。并从左到右标记为1, 2, ... L。

现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:

  1. "C A B C" 指在A到 B 号方格中涂上颜色 C。
  2. "P A B" 指老师的提问:A到 B号方格中有几种颜色。

学校的颜料盒中一共有 T 种颜料。为简便起见,我们把他们标记为 1, 2, ... T. 开始时色板上原有的颜色就为1号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?

输入输出格式

输入格式:

第一行有3个整数 L (1 <= L <= 100000), T (1 <= T <= 30) 和 O (1 <= O <= 100000)。 在这里O表示事件数。
接下来 O 行, 每行以 "C A B C" 或 "P A B" 得形式表示所要做的事情(这里 A, B, C 为整数, 可能A> B,这样的话需要你交换A和B)

输出格式:

对于老师的提问,做出相应的回答。每行一个整数。

输入输出样例

输入样例#1: 复制
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
输出样例#1: 复制
2
1


只有取答案的时候是加异或
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
const int N=100000;

int sum[N<<2],col[N<<2],n,m,t,cnt,a,b,k,c;

int getans(int x)
{
    int cnt=0;
    while(x)
    {
        if(x&1)cnt++;
        x>>=1;
    }
    return cnt;
}
void up(int pos)
{
    sum[pos]=(sum[pos<<1]|sum[pos<<1|1]);
}
void build(int l,int r,int pos)
{
    col[pos]=0;
    if(l==r){sum[pos]=1; return ;}
    int m=(l+r)>>1;
    build(lson);build(rson);
    up(pos);
}
void down(int pos)
{
    if(col[pos])
    {
        col[pos<<1]=col[pos];
        col[pos<<1|1]=col[pos];
        sum[pos<<1]=col[pos];
        sum[pos<<1|1]=col[pos];
        col[pos]=0;
    }
}
void update(int L,int R,int v,int l,int r,int pos)
{
    if(L<=l&&r<=R)
    {
        col[pos]=(1<<(v-1));
        sum[pos]=(1<<(v-1));
        return ;
    }
    down(pos);
    int m=(l+r)>>1;
    if(L<=m)update(L,R,v,lson);
    if(R>m)update(L,R,v,rson);
    up(pos);
}

void query(int L,int R,int l,int r,int pos)
{
    if(L<=l&&r<=R)
    {
        cnt|=sum[pos];
        return ;
    }
    int m=(l+r)>>1;
    down(pos);
    if(L<=m)query(L,R,lson);
    if(R>m)query(L,R,rson);
    up(pos);
}

char s[3];
int main()
{
    RIII(n,t,k);
    build(1,n,1);

    while(k--)
    {
        RS(s);
        if(s[0]=='C')
        {
            RIII(a,b,c);if(a>b)swap(a,b);
            update(a,b,c,1,n,1);
        }
        else
        {
            cnt=0;
            RII(a,b);if(a>b)swap(a,b);
            query(a,b,1,n,1);
            cout<<getans(cnt)<<endl;
        }
    }
    return 0;
}
View Code






原文地址:https://www.cnblogs.com/bxd123/p/10928131.html