1. 程式人生 > >bzoj 3730 震波 - 動態點分治 - BIT

bzoj 3730 震波 - 動態點分治 - BIT

垃圾卡常題bz上過不了

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define N 100010
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" " #define ln <<endl using namespace std; typedef pair<int,int> pii; typedef set<int>::iterator sit; inline int inn() { int x,ch;while((ch=gc)<'0'||ch>'9'); x=ch^'0';while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0'
);return x; } unordered_map<int,pii> zid[N]; struct edges{ int to,pre; }e[N<<1];int *b[N],**bv[N],sr[N],*srv[N]; int h[N],etop,ds[N],sz[N],in[N],out[N],tms[N],dfc,Lst[N],Lcnt,vis[N],dpt[N],val[N],fa[N]; inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop;
} inline int update(int* &b,int p,int n,int v) { for(;p<=n;p+=(p&-p)) b[p]+=v;return 0; } inline int query(int* &b,int p) { int ans=0;for(;p;p^=(p&-p)) ans+=b[p];return ans; } inline int build(int* &b,int n) { b=new int[n+1],b[0]=0; ds[0]=0;rep(i,1,n) ds[i]+=ds[i-1]; rep(i,1,n) b[i]=ds[i]-ds[i-(i&-i)]; return 0; } int getsz(int x,int f=0) { sz[x]=1,Lst[++Lcnt]=x; for(int i=h[x],y;i;i=e[i].pre) if(!vis[y=e[i].to]&&e[i].to!=f) sz[x]+=getsz(y,x); return sz[x]; } inline int getrt(int &x) { for(int i=1,fsz=sz[x],t=fsz;i<=Lcnt;i++) { int y=Lst[i],ysz=fsz-sz[y]; for(int j=h[y],z;j;j=e[j].pre) if(!vis[z=e[j].to]) if(sz[z]<sz[y]) ysz=max(ysz,sz[z]); if(ysz<t) t=ysz,x=y; } return Lcnt=0; } int getdz(int x,int f,int z,int d,int c) { zid[z][x]=mp(c,d),dpt[x]=1,tms[in[x]=++dfc]=x; for(int i=h[x],y;i;i=e[i].pre) if(!vis[y=e[i].to]&&e[i].to!=f) getdz(y,x,z,d+1,c),dpt[x]=max(dpt[x],dpt[y]+1); return out[x]=dfc; } int solve(int x,int f) { Lcnt=0,getsz(x),getrt(x),fa[x]=f,vis[x]=1,dfc=0,dpt[x]=1;int cnt=0; for(int i=h[x],y;i;i=e[i].pre) if(!vis[y=e[i].to]) getdz(y,x,x,2,cnt),dpt[x]=max(dpt[x],dpt[y]+1),cnt++; memset(ds,0,sizeof(int)*(dpt[x]+1)); rep(i,1,dfc) ds[zid[x][tms[i]].sec]+=val[tms[i]]; ds[1]+=val[x],build(b[x],sr[x]=dpt[x]); bv[x]=new int*[cnt],srv[x]=new int[cnt],cnt=0; for(int i=h[x],y;i;i=e[i].pre) if(!vis[y=e[i].to]) { memset(ds,0,sizeof(int)*(dpt[y]+2)); rep(j,in[y],out[y]) ds[zid[x][tms[j]].sec]+=val[tms[j]]; build(bv[x][cnt],srv[x][cnt]=dpt[y]+1),cnt++; } for(int i=h[x],y;i;i=e[i].pre) if(!vis[y=e[i].to]) solve(y,x); return 0; } inline int update(int x,int v) { val[x]+=v,update(b[x],1,sr[x],v); for(int y=fa[x],z,d;y;y=fa[y]) z=zid[y][x].fir,d=zid[y][x].sec, update(b[y],d,sr[y],v), update(bv[y][z],d,srv[y][z],v); return 0; } inline int query(int x,int k) { int ans=query(b[x],min(sr[x],k+1)); for(int y=fa[x],z,d;y;y=fa[y]) { z=zid[y][x].fir,d=zid[y][x].sec; if(k+1>=d) ans+=query(b[y],min(sr[y],k-d+2))-query(bv[y][z],min(srv[y][z],k-d+2)); } return ans; } char ss[N*14],tt[20];int ssl,ttl; inline int show(int x) { if(!x) ss[++ssl]='0';for(ttl=0;x;x/=10) tt[++ttl]=char(x%10+'0'); for(;ttl;ttl--) ss[++ssl]=tt[ttl];return ss[++ssl]='\n'; } int main() { int n=inn(),m=inn(),x,y;rep(i,1,n) val[i]=inn(); rep(i,1,n-1) x=inn(),y=inn(),add_edge(x,y),add_edge(y,x); solve(1,0); for(int i=1,las=0;i<=m;i++) { int tp=inn(),x=inn()^las,y=inn()^las; if(!tp) show(las=query(x,y)); else update(x,y-val[x]); } return fwrite(ss+1,sizeof(char),ssl,stdout),0; }