bzoj1146整体二分+树链剖分+树状数组
Posted 我的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于bzoj1146整体二分+树链剖分+树状数组的主要内容,如果未能解决你的问题,请参考以下文章