hdu 5023 (线段树 )

                             这道题当时没有做出来,状态不会保存。原来可已用二进制保存状态,做的题太少,暴漏的问题太多了;这么简单的东西,,,,,也不会保存

                            这道题就是每一次维护区间的和,也就是把它的30种颜色用二进制保存下来。也就1<<30   可以用long  long  保存下来

                            

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxx  1111111
#define lson L,m,rt<<1
#define rson m+1,R,rt<<1|1
typedef long long ll;
int cnt;
ll add[maxx<<2];
int ans[50];
ll sum[maxx<<2];
int n,m;

void pushup(int rt){
   sum[rt]=sum[rt<<1]|sum[rt<<1|1];
}

void pushdown(int rt){
     if(add[rt]){
         add[rt<<1]=add[rt];
         add[rt<<1|1]=add[rt];
         sum[rt<<1]=add[rt];
         sum[rt<<1|1]=add[rt];
         add[rt]=0;
     }
}

void build(int L,int R,int rt){
     add[rt]=0;
     if(L==R){
        sum[rt]=2;(颜色2相当于1<<1,那么颜色1就1<<0)
        return ;
     }
     int m=(L+R)>>1;
     build(lson);
     build(rson);
     pushup(rt);
}

void update(int l,int r,int  c,int L,int R,int rt){
     if(l<=L&&R<=r){
        add[rt]=1<<(c-1);
        sum[rt]=1<<(c-1);
        return ;
     }
     pushdown(rt);
     int m=(L+R)>>1;
     if(l<=m) update(l,r,c,lson);
     if(m<r)  update(l,r,c,rson);
     pushup(rt);
}

ll query(int l,int r,int L,int R,int rt){
      ll ret=0;
      if(l<=L&&r>=R){
       return sum[rt];
      }
      pushdown(rt);
      int m=(L+R)>>1;
      if(l<=m) ret|=query(l,r,lson);
      if(m<r)  ret|=query(l,r,rson);
      return ret;
}

int main(){
      while(scanf("%d%d",&n,&m)!=EOF){
      if(n==0&&m==0) break;
      build(1,n,1);
      while(m--){
        char op[2];
        scanf("%s",op);
        int a,b,c;
        if(op[0]=='P'){
            scanf("%d%d%d",&a,&b,&c);
            update(a,b,c,1,n,1);
        }
        else {
            memset(ans,0,sizeof(ans));
            cnt=0;
            scanf("%d%d",&a,&b);
            ll r=query(a,b,1,n,1);
            for(int i=0;i<30;i++){
                if(r&(1<<i)){
                    ans[cnt++]=i+1;
                }
            }
            int flag =0;
            for(int i=0;i<cnt;i++){
                if(flag){
                    printf(" %d",ans[i]);
                }
                else {
                    printf("%d",ans[i]);
                    flag =1 ;
                }
            }
            puts("");
        }
      }
}
}

你可能感兴趣的:(hdu 5023 (线段树 ))