Duty Address: http://www. Lydsy. Com/judgeonline/problem. Php?
id = 3531
Title Effect: See the original title.
Algorithm discussion: Tree chain splitting.
We can.
Code:
#include <cstdio> #include <algorithm> #define N 3000000#define M 30000000#define oo 0x7f7f7f7fusing Namespace Std;int n,q,x,y,mm,tot,digit[10],w[n+10],c[n+10],next[n+10],son[n+10],ed[n+10],fa[n+10],head[n+10], HEAVY[N+10], Size[n+10],deep[n+10],id[n+10],tree1[m+10],tree2[m+10],l[n+10],r[n+10],root[n+10];bool vis[N+10]; Char s[10];void Add (int x,int y) {next[++mm]=son[x]; son[x]=mm; Ed[mm]=y;} void dfs1 (int x) {vis[x]=1; Size[x]=1; for (int i=son[x];i;i=next[i]) {int y=ed[i]; if (!vis[y]) {fa[y]=x; deep[y]=deep[x]+1; DFS1 (y); Size[x]+=size[y]; if (Size[y]>size[heavy[x]]) heavy[x]=y; }}}void DFS2 (int x) {vis[x]=1; Id[x]=++tot; if (!head[x]) head[x]=x; if (Heavy[x]) {head[heavy[x]]=head[x]; DFS2 (Heavy[x]); } for (int i=son[x];i;i=next[i]) {int y=ed[i]; if (!vis[y]) dfs2 (y); }}void up (int rt) {TREE1[RT]=TREE1[L[RT]]+TREE1[R[RT]]; Tree2[rt]=max (Tree2[l[rt]],tree2[r[rt]);} void Modify (int& rt,int lc,int rc,int x,int y) {if (!rt) Rt=++tot; if (LC==RC) {tree1[rt]=y; Tree2[rt]=y; Return } int mid= (LC+RC)/2; if (x<=mid) modify (l[rt],lc,mid,x,y); else modify (r[rt],mid+1,rc,x,y); Up (RT);} int qsum (int rt,int lc,int rc,int l,int R) {if (!RT) return 0; if (L==LC && R==RC) return TREE1[RT]; int mid= (LC+RC)/2; if (R<=mid) return qsum (L[RT],LC,MID,L,R); if (L>mid) return qsum (R[RT],MID+1,RC,L,R); Return Qsum (L[rt],lc,mid,l,mid) +qsum (r[rt],mid+1,rc,mid+1,r);} int Qmax (int rt,int lc,int rc,int l,int R) {if (!RT) return 0; if (L==LC && R==RC) return TREE2[RT]; int mid= (LC+RC)/2; if (R<=mid) return Qmax (L[RT],LC,MID,L,R); if (L>mid) return Qmax (R[RT],MID+1,RC,L,R); Return Max (Qmax (L[rt],lc,mid,l,mid), Qmax (R[rt],mid+1,rc,mid+1,r));} int qs (int x,int y) {int ans=0,c=c[x]; while (Head[x]!=head[y]) {if (dEep[head[x]]<deep[head[y]]) swap (x, y); Ans+=qsum (Root[c],1,n,id[head[x]],id[x]); X=FA[HEAD[X]]; } if (Deep[x]>deep[y]) swap (x, y); Ans+=qsum (Root[c],1,n,id[x],id[y]); return ans;} int QM (int x,int y) {int ans=-oo,c=c[x]; while (Head[x]!=head[y]) {if (deep[head[x]]<deep[head[y])) swap (x, y); Ans=max (Ans,qmax (root[c],1,n,id[head[x]],id[x)); X=FA[HEAD[X]]; } if (Deep[x]>deep[y]) swap (x, y); Ans=max (Ans,qmax (root[c],1,n,id[x],id[y)); return ans;} int main () {#ifndef Online_judge freopen ("3531.in", "R", stdin); Freopen ("3531.out", "w", stdout); #endif scanf ("%d%d", &n,&q); for (int i=1;i<=n;++i) scanf ("%d%d", &w[i],&c[i]); for (int i=1;i<n;++i) {scanf ("%d%d", &x,&y); Add (x, y); Add (y,x); } DFS1 (1); for (int i=1;i<=n;++i) vis[i]=0; DFS2 (1); tot=0; for (int i=1;i<=n;++i) modify (Root[c[i]],1,n,id[i],w[i]); for (int i=1;i<=q;++i){scanf ("%s%d%d", s,&x,&y); if (s[0]== ' C ') if (s[1]== ' C ') {modify (root[c[x]],1,n,id[x],0); Modify (Root[y],1,n,id[x],w[x]); C[x]=y; } else{Modify (Root[c[x]],1,n,id[x],y); W[x]=y; } else if (s[1]== ' s ') printf ("%d\n", QS (x, y)); else printf ("%d\n", QM (x, y)); } return 0;}
by Charlie Pan
Mar 14,2014
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
Bzoj 3531: [Sdoi2014] Travel