(2016北京集训十三)【xsy1533】mushroom - bitset

题解:

神题。。。我看到的时候直接吓懵了。。。

这是一道STL题。。。否则可能要写可持久化ETT或者可持久化Toptree?

用bitset来维护每个蘑菇上哪里有杂草,那么

对于操作1和操作2:可以预处理每个点为跟的bitset;

对于操作3和操作4:预处理两个点到根这条链上的bitset,先异或再或两个点的lca的bitset;

对于操作5和操作6:直接暴力区间清零即可;

询问直接贪心,由于随机所以复杂度O(玄学)(实际上应该是$O(\frac{n}{32}+\frac{n}{ln200})$?)

用STL的bitset会T掉一个点。。。所以我只能看着dalao们的手写bitset瑟瑟发抖(然而也并没有完全看懂)

代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 #define inf 2147483647
  9 #define eps 1e-9
 10 using namespace std;
 11 typedef long long ll;
 12 typedef unsigned int uint;
 13 struct edge{
 14     int v,next;
 15 }a[100001];
 16 int n,m,u,v,op,L,now,cnt=1,tot=0,lg[65537],dep[50001],head[500001],rts[50001],fa[50001][17];
 17 uint *bt[100001],s1[50001][1601],s2[50001][1601];
 18 map<uint*,int>mp;
 19 void New(int k){
 20     bt[++cnt]=bt[k];
 21     mp[bt[cnt]]++;
 22 }
 23 void clr(int l,int r){
 24     if(r-l<40){
 25         for(int i=l;i<=r;i++){
 26             bt[now][i>>5]&=~((uint)1<<(i&31));
 27         }
 28         return;
 29     }
 30     int L=(l>>5)+1,R=(r>>5)-1;
 31     for(int i=L;i<=R;i++)bt[now][i]=0;
 32     for(int i=l;(i>>5)!=L;i++)bt[now][i>>5]&=~((uint)1<<(i&31));
 33     for(int i=r;(i>>5)!=R;i--)bt[now][i>>5]&=~((uint)1<<(i&31));
 34 }
 35 void rec(int k){
 36     if(mp[bt[k]]>1){
 37         uint *bb=bt[k];
 38         bt[k]=(uint*)malloc(L*sizeof(uint));
 39         mp[bt[k]]++;
 40         for(int i=0;i<L;i++)bt[k][i]=bb[i];
 41         mp[bt[k]]--;
 42     }
 43 }
 44 void Or(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]|=b[i];}
 45 void And(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]&=b[i];}
 46 void Nand(uint a[],uint b[]){for(int i=0;i<L;i++)a[i]&=~b[i];}
 47 void AND(uint a[],uint b[],uint c[],int k){
 48     uint t=a[k>>5]>>(k&31)&1;
 49     for(int i=0;i<L;i++)a[i]&=b[i]^c[i];
 50     a[k>>5]|=t<<(k&31);
 51 }
 52 void NAND(uint a[],uint b[],uint c[],int k){
 53     for(int i=0;i<L;i++)a[i]&=~(b[i]^c[i]);
 54     a[k>>5]&=~((uint)1<<(k&31));
 55 }
 56 void add(int u,int v){
 57     a[++tot].v=v;
 58     a[tot].next=head[u];
 59     head[u]=tot;
 60 }
 61 void dfs(int u,int ff,int dpt){
 62     dep[u]=dpt;
 63     fa[u][0]=ff;
 64     for(int i=1;i<=16;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
 65     for(int i=0;i<L;i++)s1[u][i]=s1[ff][i];
 66     s1[u][u>>5]^=(uint)1<<(u&31);
 67     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
 68         int v=a[tmp].v;
 69         if(v!=ff){
 70             dfs(v,u,dpt+1);
 71         }
 72     }
 73     s2[u][u>>5]^=(uint)1<<(u&31);
 74     for(int i=0;i<L;i++)s2[ff][i]|=s2[u][i];
 75 }
 76 int lca(int u,int v){
 77     if(dep[u]<dep[v])swap(u,v);
 78     int l=dep[u]-dep[v];
 79     for(int i=16;i>=0;i--){
 80         if((1<<i)&l)u=fa[u][i];
 81     }
 82     if(u==v)return u;
 83     for(int i=16;i>=0;i--){
 84         if(fa[u][i]!=fa[v][i]){
 85             u=fa[u][i],v=fa[v][i];
 86         }
 87     }
 88     return fa[u][0];
 89 }
 90 int query(int k){
 91     int ans=0;
 92     for(int i=1;i<=n;){
 93         if(bt[now][i>>5]>>(i&31)){
 94             uint t=(bt[now][i>>5]>>(i&(uint)31))<<(i&31),tt=t&-t;
 95             //printf("%lld %lld %lld\n",(ll)bt[now][i>>5],(ll)t,(ll)tt);
 96             if(tt>65536)tt=lg[tt>>16]+16;
 97             else tt=lg[tt];
 98             ans++;
 99             i=((i&(~(uint)31))|tt)+k+1;
100         }else i=((i>>5)+1)<<5;
101     }
102     return ans;
103 }
104 int main(){
105     memset(head,-1,sizeof(head));
106     scanf("%d",&n);
107     for(int i=1;i<n;i++){
108         scanf("%d%d",&u,&v);
109         add(u,v);
110         add(v,u);
111     }
112     L=(n+32)>>5;
113     for(int i=0;i<=16;i++)lg[1<<i]=i;
114     bt[0]=(uint*)malloc(L*sizeof(uint));
115     bt[1]=(uint*)malloc(L*sizeof(uint));
116     for(int i=0;i<L;i++)bt[0][i]=bt[1][i]=0;
117     for(int i=1;i<=n;i++)bt[1][i>>5]|=(uint)1<<(i&31);
118     dfs(1,0,1);
119     scanf("%d",&m);
120     for(int i=1;i<=m;i++){
121         scanf("%d%d",&op,&now);
122         switch(op){
123             case 1:{New(now);break;}
124             case 2:{
125                 scanf("%d",&u);
126                 rec(now);
127                 Or(bt[now],bt[u]);
128                 break;
129             }
130             case 3:{
131                 scanf("%d",&u);
132                 rec(now);
133                 Nand(bt[now],s2[u]);
134                 break;
135             }
136             case 4:{
137                 scanf("%d",&u);
138                 rec(now);
139                 And(bt[now],s2[u]);
140                 break;
141             }
142             case 5:{
143                 scanf("%d%d",&u,&v);
144                 rec(now);
145                 NAND(bt[now],s1[u],s1[v],lca(u,v));
146                 break;
147             }
148             case 6:{
149                 scanf("%d%d",&u,&v);
150                 rec(now);
151                 AND(bt[now],s1[u],s1[v],lca(u,v));
152                 break;
153             }
154             case 7:{
155                 scanf("%d%d",&u,&v);
156                 rec(now);
157                 clr(u,v);
158                 break;
159             }
160             case 8:{
161                 scanf("%d%d",&u,&v);
162                 rec(now);
163                 clr(1,u-1),clr(v+1,n);
164                 break;
165             }
166             case 9:{
167                 scanf("%d",&u);
168                 printf("%d\n",query(u));
169                 break;
170             }
171         }
172     }
173     return 0;
174 }

猜你喜欢

转载自www.cnblogs.com/dcdcbigbig/p/9696671.html