我觉得我要把BZOJ上的链剖写完了吧。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100500 #define maxe 200500 using namespace std; struct edge { int v,w,nxt; }e[maxe]; int n,x[maxv],y[maxv],nume=0,g[maxv]; int dis[maxv],size[maxv],son[maxv],fath[maxv],w[maxv],top[maxv],fw[maxv],cnt=0,cc[maxv]; int ls[maxv<<2],rs[maxv<<2],add[maxv<<2],lazy[maxv<<2],mx[maxv<<2],tot=0,root; char type[10]; int a,b,c; void addedge(int u,int v,int w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } void dfs1(int x) { size[x]=1;son[x]=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath[x]) { fath[v]=x;dis[v]=dis[x]+1; dfs1(v); size[x]+=size[v]; if (size[v]>size[son[x]]) son[x]=v; } } } void dfs2(int x) { w[x]=++cnt;fw[cnt]=x; if (son[fath[x]]==x) top[x]=top[fath[x]];else top[x]=x; if (son[x]!=0) dfs2(son[x]); for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath[x]) { if (v!=son[x]) dfs2(v); cc[w[v]]=e[i].w; } } } void build(int &now,int left,int right) { now=++tot;lazy[now]=0;add[now]=0; if (left==right) { mx[now]=cc[left]; return; } int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); mx[now]=max(mx[ls[now]],mx[rs[now]]); } void pushdown(int now,int left,int right) { if (lazy[now]!=0) { lazy[ls[now]]=lazy[rs[now]]=mx[ls[now]]=mx[rs[now]]=lazy[now]; add[ls[now]]=add[rs[now]]=0; lazy[now]=0; } if (add[now]!=0) { add[ls[now]]+=add[now];add[rs[now]]+=add[now]; mx[ls[now]]+=add[now];mx[rs[now]]+=add[now]; add[now]=0; } } void modify(int now,int left,int right,int l,int r,int x,int type) { pushdown(now,left,right); if ((left==l) && (right==r)) { if (type==1) {lazy[now]=x;add[now]=0;mx[now]=x;return;} else {add[now]+=x;mx[now]+=x;return;} } int mid=(left+right)>>1; if (r<=mid) modify(ls[now],left,mid,l,r,x,type); else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x,type); else { modify(ls[now],left,mid,l,mid,x,type); modify(rs[now],mid+1,right,mid+1,r,x,type); } mx[now]=max(mx[ls[now]],mx[rs[now]]); } int ask(int now,int left,int right,int l,int r) { pushdown(now,left,right); if ((left==l) && (right==r)) return mx[now]; int mid=(left+right)>>1; if (r<=mid) return ask(ls[now],left,mid,l,r); else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r); else return max(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+1,right,mid+1,r)); } void work(int type) { int f1=top[a],f2=top[b],ret=0; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(a,b);} if (type==1) modify(root,1,cnt,w[f1],w[a],c,1); else if (type==2) modify(root,1,cnt,w[f1],w[a],c,2); else ret=max(ret,ask(root,1,cnt,w[f1],w[a])); a=fath[f1];f1=top[a]; } if (a!=b) { if (dis[a]>dis[b]) swap(a,b); if (type==1) modify(root,1,cnt,w[son[a]],w[b],c,1); else if (type==2) modify(root,1,cnt,w[son[a]],w[b],c,2); else ret=max(ret,ask(root,1,cnt,w[son[a]],w[b])); } if (type==3) printf("%d\n",ret); } int main() { scanf("%d",&n); for (int i=1;i<=n-1;i++) { scanf("%d%d%d",&x[i],&y[i],&a); addedge(x[i],y[i],a); addedge(y[i],x[i],a); } dfs1(1); dfs2(1); build(root,1,cnt); for (;;) { scanf("%s",type); if (type[0]=='S') break; if ((type[0]=='C') && (type[1]=='h')) { scanf("%d%d",&a,&b); int u=x[a],v=y[a]; if (fath[u]==v) swap(u,v); modify(root,1,cnt,w[v],w[v],b,1); } else if ((type[0]=='C') && (type[1]=='o')) {scanf("%d%d%d",&a,&b,&c);work(1);} else if (type[0]=='A') {scanf("%d%d%d",&a,&b,&c);work(2);} else {scanf("%d%d",&a,&b);work(3);} } return 0; }