CF620E New Year Tree(线段树+二进制)

题解

弱智题,二进制表示位数。合并时用|

就是被1<<x卡了好久。

要写成1ll<<x才行

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<cstdio>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=400010;
  8 int cnt,head[N];
  9 int id[N],size[N],cao[N],tot; 
 10 int n,m,a[N];
 11 struct edge{
 12     int to,nxt;
 13 }e[N*2];
 14 struct tree{
 15     int l,r,lazy;
 16     long long sum;
 17 }tr[N*9];
 18 void add(int u,int v){
 19     cnt++;
 20     e[cnt].nxt=head[u];
 21     e[cnt].to=v;
 22     head[u]=cnt;
 23 }
 24 void dfs1(int u,int fa){
 25     id[u]=++tot;
 26     cao[tot]=u;
 27     size[u]=1;
 28     for(int i=head[u];i;i=e[i].nxt){
 29         int v=e[i].to;
 30         if(v==fa)continue;
 31         dfs1(v,u);
 32         size[u]+=size[v];
 33     }
 34 }
 35 void build(int l,int r,int now){
 36     tr[now].l=l;
 37     tr[now].r=r;
 38     if(l==r){
 39         tr[now].sum=1ll<<a[cao[l]];
 40         return;
 41     }
 42     int mid=(l+r)>>1;
 43     build(l,mid,now*2);
 44     build(mid+1,r,now*2+1);
 45     tr[now].sum=tr[now*2].sum|tr[now*2+1].sum;
 46 }
 47 void pushdown(int now){
 48     if(tr[now].lazy==0)return;
 49     tr[now*2].sum=tr[now*2+1].sum=1ll<<tr[now].lazy;
 50     tr[now*2].lazy=tr[now*2+1].lazy=tr[now].lazy;
 51     tr[now].lazy=0;
 52 }
 53 void update(int l,int r,int now,int c){
 54     pushdown(now);
 55     if(tr[now].l==l&&tr[now].r==r){
 56         tr[now].sum=1ll<<c;
 57         tr[now].lazy=c;
 58         return;
 59     }
 60     int mid=(tr[now].l+tr[now].r)>>1;
 61     if(l>mid)update(l,r,now*2+1,c);
 62     else if(r<=mid)update(l,r,now*2,c);
 63     else{
 64         update(l,mid,now*2,c);
 65         update(mid+1,r,now*2+1,c);
 66     }
 67     tr[now].sum=tr[now*2].sum|tr[now*2+1].sum;
 68 }
 69 long long query(int l,int r,int now){
 70     pushdown(now);
 71     if(tr[now].l==l&&tr[now].r==r){
 72         return tr[now].sum;
 73     }
 74     int mid=(tr[now].l+tr[now].r)>>1;
 75     if(l>mid)return query(l,r,now*2+1);
 76     else if(r<=mid)return query(l,r,now*2);
 77     else{
 78         return query(l,mid,now*2)|query(mid+1,r,now*2+1);
 79     }
 80 }
 81 int work(long long x){
 82     int ans=0;
 83     while(x){
 84         if(x&1)ans++;
 85         x>>=1;
 86     }
 87     return ans;
 88 }
 89 int main(){
 90     scanf("%d%d",&n,&m);
 91     for(int i=1;i<=n;i++){
 92         scanf("%d",&a[i]);
 93     }
 94     for(int i=1;i<n;i++){
 95         int u,v;
 96         scanf("%d%d",&u,&v);
 97         add(u,v);add(v,u);
 98     }
 99     dfs1(1,0);
100     build(1,n,1);
101     for(int i=1;i<=m;i++){
102         int k;
103         scanf("%d",&k);
104         if(k==1){
105             int u,c;
106             scanf("%d%d",&u,&c);
107         //    cout<<id[u]<<" "<<id[u]+size[u]-1<<endl;
108             update(id[u],id[u]+size[u]-1,1,c);
109         }
110         else{
111             int u;
112             scanf("%d",&u);
113             printf("%d\n",work(query(id[u],id[u]+size[u]-1,1)));
114         }
115     }
116     return 0;
117 }
View Code

 

posted @ 2018-08-01 17:59  Xu-daxia  阅读(279)  评论(0编辑  收藏  举报