bzoj1146全體二分+樹鏈剖分+樹狀數組。本站提示廣大學習愛好者:(bzoj1146全體二分+樹鏈剖分+樹狀數組)文章只能為提供參考,不一定能成為您想要的結果。以下是bzoj1146全體二分+樹鏈剖分+樹狀數組正文
其實也沒啥好說的
用樹狀數組可以O(logn)的查詢
套一層全體二分就可以做到O(nlngn)
最後用樹鏈剖分讓序列上樹
1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 using namespace std;
6 inline int read()
7 {
8 int x=0,f=1,ch=getchar();
9 while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}
10 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
11 return x*f;
12 }
13 int n,q;
14 int data[80005];
15 inline void add(int x,int i)
16 {
17 while(x<=n)
18 {
19 data[x]+=i;
20 x+=x&(-x);
21 }
22 }
23 inline int query(int x)
24 {
25 int res=0;
26 while(x>=1)
27 {
28 res+=data[x];
29 x-=x&(-x);
30 }
31 return res;
32 }
33 int h[80005],next[160005],to[160005],cnt;
34 inline void addedge(int x,int y)
35 {
36 next[cnt]=h[x];
37 to[cnt]=y;
38 h[x]=cnt;
39 cnt++;
40 }
41 int size[80005],hson[80005],dep[80005],f[80005];
42 inline void bfs(int x,int fa)
43 {
44 int i;
45 size[x]=1;
46 for(i=h[x];i!=-1;i=next[i])
47 {
48 if(to[i]==fa)
49 {
50 continue;
51 }
52 dep[to[i]]=dep[x]+1;
53 f[to[i]]=x;
54 bfs(to[i],x);
55 size[x]+=size[to[i]];
56 if(size[to[i]]>size[hson[x]])
57 {
58 hson[x]=to[i];
59 }
60 }
61 }
62 int up[80005],first[80005],tim;
63 inline void spfa(int x,int tt)
64 {
65 tim++;
66 first[x]=tim;
67 up[x]=tt;
68 if(!hson[x])
69 {
70 return ;
71 }
72 spfa(hson[x],tt);
73 int i;
74 for(i=h[x];i!=-1;i=next[i])
75 {
76 if(to[i]==f[x]||to[i]==hson[x])
77 {
78 continue;
79 }
80 spfa(to[i],to[i]);
81 }
82 }
83 inline int lca(int x,int y)
84 {
85 int res=0;
86 while(up[x]!=up[y])
87 {
88 if(dep[up[x]]<dep[up[y]])
89 {
90 swap(x,y);
91 }
92 res+=query(first[x])-query(first[up[x]]-1);
93 x=f[up[x]];
94 }
95 if(dep[x]>dep[y])
96 {
97 swap(x,y);
98 }
99 res+=query(first[y])-query(first[x]-1);
100 return res;
101 }
102 struct stu
103 {
104 int op,l,r,id,x;
105 };
106 stu a[240005];
107 int ans[80005];
108 int m[240005];
109 stu q1[240005],q2[240005];
110 inline void erfen(int l,int r,int sl,int sr)
111 {
112 if(sl>sr)
113 {
114 return ;
115 }
116 if(l==r)
117 {
118 int i;
119 for(i=sl;i<=sr;i++)
120 {
121 if(a[i].op!=2)
122 {
123 continue;
124 }
125 ans[a[i].id]=l;
126 }
127 return ;
128 }
129 int i,mid=(l+r)>>1,k,cnt1=0,cnt2=0;
130 for(i=sl;i<=sr;i++)
131 {
132 if(a[i].op==0)
133 {
134 if(a[i].x<=mid)
135 {
136 add(first[a[i].l],1);
137 m[i]=0;
138 }
139 else
140 {
141 m[i]=1;
142 }
143 continue;
144 }
145 if(a[i].op==1)
146 {
147 if(a[i].x<=mid)
148 {
149 add(first[a[i].l],-1);
150 m[i]=0;
151 }
152 else
153 {
154 m[i]=1;
155 }
156 continue;
157 }
158 if(a[i].op==2)
159 {
160 k=lca(a[i].l,a[i].r);
161 if(k<a[i].x)
162 {
163 a[i].x-=k;
164 m[i]=1;
165 }
166 else
167 {
168 m[i]=0;
169 }
170 }
171 }
172 for(i=sl;i<=sr;i++)
173 {
174 if(a[i].op==0)
175 {
176 if(a[i].x<=mid)
177 {
178 add(first[a[i].l],-1);
179 }
180 }
181 if(a[i].op==1)
182 {
183 if(a[i].x<=mid)
184 {
185 add(first[a[i].l],1);
186 }
187 }
188 if(m[i]==0)
189 {
190 cnt1++;
191 q1[cnt1]=a[i];
192 }
193 else
194 {
195 cnt2++;
196 q2[cnt2]=a[i];
197 }
198 }
199 for(i=1;i<=cnt1;i++)
200 {
201 a[sl+i-1]=q1[i];
202 }
203 for(i=1;i<=cnt2;i++)
204 {
205 a[sl+cnt1+i-1]=q2[i];
206 }
207 erfen(l,mid,sl,sl+cnt1-1);
208 erfen(mid+1,r,sl+cnt1,sr);
209 }
210 int p[80005];
211 int main()
212 {
213 memset(h,-1,sizeof(h));
214 memset(ans,0x3f,sizeof(ans));
215 n=read(),q=read();
216 int i,x,y,tail=0,k,o;
217 for(i=1;i<=n;i++)
218 {
219 x=read();
220 tail++;
221 a[tail].op=0,a[tail].l=i,a[tail].x=x;
222 p[i]=x;
223 }
224 for(i=1;i<n;i++)
225 {
226 x=read(),y=read();
227 addedge(x,y);
228 addedge(y,x);
229 }
230 dep[1]=1;
231 bfs(1,-1);
232 spfa(1,1);
233 for(i=1;i<=n;i++)
234 {
235 add(first[i],1);
236 }
237 for(i=1;i<=q;i++)
238 {
239 k=read(),x=read(),y=read();
240 if(k==0)
241 {
242 tail++;
243 a[tail].op=1;a[tail].l=x,a[tail].x=p[x];
244 tail++;
245 a[tail].op=0;a[tail].l=x;a[tail].x=y;
246 p[x]=y;
247 }
248 else
249 {
250 o=lca(x,y);
251 if(o<k)
252 {
253 ans[i]=-1;
254 continue;
255 }
256 k=o-k+1;
257 tail++;
258 a[tail].op=2,a[tail].l=x,a[tail].r=y,a[tail].x=k;
259 a[tail].id=i;
260 }
261 }
262 memset(data,0,sizeof(data));
263 erfen(0,100000000,1,tail);
264 for(i=1;i<=q;i++)
265 {
266 if(ans[i]==0x3f3f3f3f)
267 {
268 continue;
269 }
270 if(ans[i]==-1)
271 {
272 puts("invalid request!");
273 }
274 else
275 {
276 printf("%d\n",ans[i]);
277 }
278 }
279 return 0;
280 }