bzoj3730 震波
题解:
好像和皮皮鼠那题一模一样。
代码:
#include<cstdio> #include<cstring> #include<algorithm> #define N 100050 inline int rd() { int f=1,c=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int n,m,v[N],hed[N],cnt; struct EG { int to,nxt; }e[2*N]; void ae(int f,int t) { e[++cnt].to = t; e[cnt].nxt = hed[f]; hed[f] = cnt; } int dep[N],fa[N],son[N],siz[N],top[N]; void dfs1(int u,int f) { fa[u] = f; siz[u] = 1; dep[u] = dep[f]+1; for(int j=hed[u];j;j=e[j].nxt) { int to = e[j].to; if(to==f)continue; dfs1(to,u); siz[u]+=siz[to]; if(siz[to]>siz[son[u]])son[u] = to; } } void dfs2(int u,int tp) { top[u] = tp; if(!son[u])return ; dfs2(son[u],tp); for(int j=hed[u];j;j=e[j].nxt) { int to = e[j].to; if(to==fa[u]||to==son[u])continue; dfs2(to,to); } } int get_lca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])std::swap(x,y); x = fa[top[x]]; } return dep[x]<dep[y]?x:y; } int get_dis(int x,int y) { return dep[x]+dep[y]-2*dep[get_lca(x,y)]; } int rt,sum,w[N],sz[N],uf[N],mrk[N]; void get_rt(int u,int f) { sz[u]=1,w[u]=0; for(int j=hed[u];j;j=e[j].nxt) { int to = e[j].to; if(mrk[to]||to==f)continue; get_rt(to,u); sz[u]+=sz[to]; if(sz[to]>w[u])w[u]=sz[to]; } if(sum-sz[u]>w[u])w[u]=sum-sz[u]; if(w[u]<w[rt])rt=u; } void work(int u) { mrk[u] = 1;int pre = sum; for(int j=hed[u];j;j=e[j].nxt) { int to = e[j].to; if(mrk[to])continue; rt = 0,sum = (sz[to]>sz[u]?pre-sz[u]:sz[to]); get_rt(to,0);uf[rt] = u; work(rt); } } struct segtree { int tot,rt[N],ls[N*80],rs[N*80],vl[N*80]; void insert(int l,int r,int &u,int qx,int d) { if(!u)u = ++tot; vl[u]+=d; if(l==r)return ; int mid = (l+r)>>1; if(qx<=mid)insert(l,mid,ls[u],qx,d); else insert(mid+1,r,rs[u],qx,d); } int query(int l,int r,int u,int qr) { if(!u)return 0; if(r==qr)return vl[u]; int mid = (l+r)>>1; if(qr<=mid)return query(l,mid,ls[u],qr); else return vl[ls[u]]+query(mid+1,r,rs[u],qr); } void push(int x,int qx,int d) { qx = qx<n?qx:n; insert(0,n,rt[x],qx,d); } int ask(int x,int lim) { return query(0,n,rt[x],lim); } }tr1,tr2; int main() { n = rd(),m = rd(); for(int i=1;i<=n;i++)v[i] = rd(); for(int f,t,i=1;i<n;i++) { f = rd(),t = rd(); ae(f,t),ae(t,f); } dfs1(1,0),dfs2(1,1); w[0]=0x3f3f3f3f,rt=0,sum=n; get_rt(1,0);work(rt); for(int i=1;i<=n;i++) { int x = i,y = 0; while(x) { int ds = get_dis(x,i); tr1.push(x,ds,v[i]); if(y)tr2.push(y,ds,v[i]); y=x,x=uf[x]; } } int opt,x,y,a,b,ds,ans = 0; for(int i=1;i<=m;i++) { opt = rd(),x = rd()^ans,y = rd()^ans; if(!opt) { a = x,b = 0; ans = 0; while(a) { ds = y - get_dis(a,x); if(ds>=0) { ans+=tr1.ask(a,ds); if(b)ans-=tr2.ask(b,ds); } b = a,a = uf[a]; } printf("%d\n",ans); }else { int dv = y - v[x]; v[x] = y; a = x,b = 0; while(a) { ds = get_dis(a,x); tr1.push(a,ds,dv); if(b)tr2.push(b,ds,dv); b = a,a = uf[a]; } } } return 0; }