有两种操作,一个是更新区间内颜色,一个是询问区间内不同颜色的个数
因为颜色最多只有30种,所以把区间内颜色数压成一个数字即可,如果(1<
因为是区间更新,所以再加个延时标记就好了。
/*===============*\ | *** *** *** *** | | * ** * * * | | *** *** * *** | | ID: ZERO | | LANG: C++ | \*===============*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define mod (int)(1e9+7) #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 #define maxn 100001 int col[maxn<<2]; bool up[maxn<<2]; int upit[maxn<<2]; void PushUP(int rt) { //向上更新 col[rt] = col[rt<<1]|col[rt<<1|1]; } void PushDown(int rt,int l,int r,int now){ //向下更新 col[now]=col[rt]; if(l!=r){ up[now]=true; upit[now]=col[rt]; } } void build(int co,int l,int r,int rt) {//建树 up[rt]=false; if (l == r) { col[rt]=co; return ; } int m = (l + r) >> 1; build(co,lson); build(co,rson); PushUP(rt); } void update(int ll,int rr,int sc,int l,int r,int rt) {//更新 if (l >=ll && r<=rr) { col[rt] = sc; if(l!=r) {up[rt]=true;upit[rt]=sc;} //延时标记 return ; } int m=(l+r) >> 1;//middle if(up[rt]){//触发延时标记 PushDown(rt,lson); PushDown(rt,rson); up[rt]=false; } if (ll<=m&&rr>=l) update(ll,rr , sc , lson); if (ll<=r&&rr>=m+1) update(ll,rr , sc , rson); PushUP(rt); } int query(int L,int R,int l,int r,int rt) {//询问 if (L <= l && r <= R) { return col[rt]; } int m=(l+r) >> 1;//middle if(up[rt]){ PushDown(rt,lson); PushDown(rt,rson); up[rt]=false; } int ret = 0; if (L <= m) ret = ret|query(L,R,lson); if (R > m) ret = ret|query(L,R,rson); return ret; } char s[2]; int main(){ int n,m,t; while (~scanf("%d%d%d",&n,&t,&m)) { build(1,1,n,1);//建树 while (m--) { int l,r,co; scanf("%s%d%d",s,&l,&r); int tt; if(l>r) tt=l,l=r,r=tt;// A may be larger than B 这条件你妹的! if(s[0]=='C'){ scanf("%d",&co); update(l,r,1<<(co-1),1,n,1); } else{ int nn=query(l,r,1,n,1),ans=0; for(int i=0;i