Point division + Line tree:
For each center of gravity, the weight segment tree is built with the distance from the point to the center of gravity, maintaining the sum of the point weights.
The modification is changed in the tree of the Logn tree segment that the point belongs to.
But obviously the query should consider the problem of the heavy ...
For the center of gravity of the current layer, make a note of which son's sub-tree in the center of gravity of the previous layer, wait for the query to the previous layer to remove this part (the corresponding sub-tree points should be given to this layer of the center of gravity calculation).
Remove the words. A new line tree is opened on the subtree, and the weight is the distance from the point in the subtree to the top of the center of gravity ... In addition, the answer in the subtree is subtracted from the answer in this layer.
Query, at the point of the query to the Logn of the center of gravity of the segment tree query, go to the weight as above.
1#include <cstdio>2#include <iostream>3#include <cstring>4#include <algorithm>5 #definell Long Long6 using namespacestd;7 Const intmaxn=100023, inf=1002333333, mxnode=10000233;8 structzs{9 intToo,pre;Ten}e[maxn<<1];intTOT,LAST[MAXN]; One introot[maxn<<1],lc[mxnode],rc[mxnode],sm[mxnode],tt; A intSz[maxn],mx[maxn],dis[maxn],val[maxn],p[maxn],mxdep[maxn],num,poi,rt; - intf[ -][maxn],dist[ -][MAXN]; - BOOLDEL[MAXN]; the inti,j,k,n,m; - - intRaCharRx; -InlineintRead () { +Rx=getchar (), ra=0; - while(rx<'0'|| Rx>'9') rx=GetChar (); + while(rx>='0'&&rx<='9') ra*=Ten, ra+=rx- -, Rx=getchar ();returnRA; A } at - - voidAddint&x,intAintBintPosintval) { - if(!x) x=++tt; -sm[x]+=Val; - if(a==b)return; in intMid=a+b>>1; - if(pos<=mid) Add (lc[x],a,mid,pos,val);ElseAdd (rc[x],mid+1, b,pos,val); to } + intQueintXintAintBintK) { - if(!x| | K>=B)returnSm[x]; the intMid=a+b>>1; * if(K>mid)returnSm[lc[x]]+que (rc[x],mid+1, b,k); $ Else returnque (lc[x],a,mid,k);Panax Notoginseng } - the + voidGETRT (intXintFA) { Asz[x]=1; the for(intI=LAST[X];I;I=E[I].PRE)if(e[i].too!=fa&&!Del[e[i].too]) +GETRT (e[i].too,x), sz[x]+=Sz[e[i].too]; -Mx[x]=max (sz[x]-1, poi-sz[x]+1); $ if(Mx[x]<mx[rt]) rt=x; $ } - voidGetpoi (intRtintXintFA) { -Add (Root[rt],0, n,dis[x],val[x]); the for(intI=LAST[X];I;I=E[I].PRE)if(e[i].too!=fa&&!Del[e[i].too]) -p[++num]=e[i].too,dis[e[i].too]=dis[x]+1, Getpoi (rt,e[i].too,x);Wuyi } the - voidWorkintDepintXintNextintPRECG) { Wu intI,CG;//Cg:center of Gravity -GETRT (x,rt=0), cg=RT; About if(next!=0) dis[next]=1, num=0, Getpoi (Cg+n,next,0); $ -del[cg]=1, mxdep[cg]=DEP; -dis[cg]=0, p[num=1]=cg,getpoi (CG,CG,0); - for(i=1; i<=num;i++) dist[dep][p[i]]=dis[p[i]],f[dep][p[i]]=CG; A + for(I=last[cg];i;i=e[i].pre)if(!Del[e[i].too]) thePoi=sz[e[i].too],work (dep+1, E[I].TOO,E[I].TOO,CG); - } $InlineintQueryintXintK) { the intI,ans=que (Root[x],0, n,k); the for(i=mxdep[x]-1; i;i--) theAns+=que (Root[f[i][x]),0, N,k-dist[i][x])-que (root[f[i+1][x]+n],0, n,k-dist[i][x]); the returnans; - } inInlinevoidChangeintXintv) { the intdelta=v-val[x],i,pre=x;val[x]=v; theAdd (Root[x],0N0, delta); About for(i=mxdep[x]-1; i;i--) theAdd (Root[f[i][x]],0, N,dist[i][x],delta), add (root[f[i+1][x]+n],0, N,dist[i][x],delta); the } theInlinevoidInsertintAintb) { +e[++tot].too=b,e[tot].pre=last[a],last[a]=tot; -e[++tot].too=a,e[tot].pre=last[b],last[b]=tot; the }Bayi the intMain () { themx[0]=inf; -N=read (), m=read (); - for(i=1; i<=n;i++) val[i]=read (); the for(i=1; i<n;i++) Insert (read (), read ()); thePoi=n,work (1,1,0,0); the the intId,la=0; - while(m--){ theId=read (), J=read (), k=read (); thej^=la,k^=LA; the if(id==0) printf ("%d\n", la=query (j,k));94 ElseChange (j,k); the } the return 0; the}
View Code
Stuck to the time of the past Tat
[bzoj3730] Shock waves