题解:
神题。。。我看到的时候直接吓懵了。。。
这是一道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
",(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
",query(u));
169 break;
170 }
171 }
172 }
173 return 0;
174 }