裸链剖。
这大概是我第一份两百行左右的代码吧。
然而我把题看错了233333333调了将近两天。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100050 #define maxe 300050 using namespace std; struct edge { int v,w,nxt; }e[maxe]; struct edge_ { int u,v,w; }eg[maxe]; char s[10]; int n,x,y,z,g[maxv],nume=0,nume_=0,m; int dis[maxv],w[maxv],top[maxv],fath[maxv],size[maxv],son[maxv],cnt=0,tot=0,c[maxv]; int ls[maxv<<2],rs[maxv<<2],lazy[maxv<<2],sum[maxv<<2],mx[maxv<<2],mn[maxv<<2],root; 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 addedge_(int u,int v,int w) { eg[++nume_].u=u; eg[nume_].v=v; eg[nume_].w=w; } void dfs1(int x,int father) { size[x]=1;son[x]=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=father) { fath[v]=x;dis[v]=dis[x]+1; dfs1(v,x); size[x]+=size[v]; if (size[v]>size[son[x]]) son[x]=v; } } } void dfs2(int x,int father) { top[x]=father;w[x]=++cnt; if (son[x]!=0) dfs2(son[x],father); 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,v); c[w[v]]=e[i].w; } } } void pushup(int now) { sum[now]=sum[ls[now]]+sum[rs[now]]; mx[now]=max(mx[ls[now]],mx[rs[now]]); mn[now]=min(mn[ls[now]],mn[rs[now]]); } void build(int &now,int left,int right) { now=++tot;lazy[now]=0; if (left==right) { sum[now]=mn[now]=mx[now]=c[left]; return; } int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); pushup(now); } void pushdown(int now,int left,int right) { int r1,r2; if (lazy[now]==1) { sum[ls[now]]=-sum[ls[now]];sum[rs[now]]=-sum[rs[now]]; r1=mn[ls[now]];r2=mx[ls[now]];mn[ls[now]]=-r2;mx[ls[now]]=-r1; r1=mn[rs[now]];r2=mx[rs[now]];mn[rs[now]]=-r2;mx[rs[now]]=-r1; lazy[ls[now]]^=1;lazy[rs[now]]^=1; lazy[now]=0; } } void modify(int now,int left,int right,int l,int r,int p,int type) { pushdown(now,left,right); if ((left==l) && (right==r)) { if (type==1) { sum[now]=p; mx[now]=p;mn[now]=p; return; } else { lazy[now]^=1; sum[now]=-sum[now]; int r1,r2;r1=mn[now];r2=mx[now]; mn[now]=-r2;mx[now]=-r1; return; } } int mid=(left+right)>>1; if (r<=mid) modify(ls[now],left,mid,l,r,p,type); else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,p,type); else { modify(ls[now],left,mid,l,mid,p,type); modify(rs[now],mid+1,right,mid+1,r,p,type); } pushup(now); } int ask(int now,int left,int right,int l,int r,int type) { pushdown(now,left,right); if ((left==l) && (right==r)) { if (type==1) return sum[now]; else if (type==2) return mx[now]; else return mn[now]; } int mid=(left+right)>>1; if (r<=mid) return ask(ls[now],left,mid,l,r,type); else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r,type); else { if (type==1) return ask(ls[now],left,mid,l,mid,type)+ask(rs[now],mid+1,right,mid+1,r,type); else if (type==2) return max(ask(ls[now],left,mid,l,mid,type),ask(rs[now],mid+1,right,mid+1,r,type)); else return min(ask(ls[now],left,mid,l,mid,type),ask(rs[now],mid+1,right,mid+1,r,type)); } } void work() { scanf("%d%d",&x,&y); x++;y++; int f1=top[x],f2=top[y]; if (s[0]=='N') { while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} modify(root,1,cnt,w[f1],w[x],0,2); x=fath[f1];f1=top[x]; } if (x!=y) { if (dis[x]>dis[y]) swap(x,y); modify(root,1,cnt,w[son[x]],w[y],0,2); } } else if (s[0]=='S') { int ans=0; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} ans+=ask(root,1,cnt,w[f1],w[x],1); x=fath[f1];f1=top[x]; } if (x!=y) { if (dis[x]>dis[y]) swap(x,y); ans+=ask(root,1,cnt,w[son[x]],w[y],1); } printf("%d\n",ans); } else if ((s[0]=='M') && (s[1]=='A')) { int ans=0xefefefef; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} ans=max(ans,ask(root,1,cnt,w[f1],w[x],2)); x=fath[f1];f1=top[x]; } if (x!=y) { if (dis[x]>dis[y]) swap(x,y); ans=max(ans,ask(root,1,cnt,w[son[x]],w[y],2)); } printf("%d\n",ans); } else { int ans=0x3f3f3f3f; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} ans=min(ans,ask(root,1,cnt,w[f1],w[x],3)); x=fath[f1];f1=top[x]; } if (x!=y) { if (dis[x]>dis[y]) swap(x,y); ans=min(ans,ask(root,1,cnt,w[son[x]],w[y],3)); } printf("%d\n",ans); } } int main() { scanf("%d",&n); for (int i=1;i<=n-1;i++) { scanf("%d%d%d",&x,&y,&z); x++;y++; addedge(x,y,z); addedge(y,x,z); addedge_(x,y,z); } dfs1(1,1); dfs2(1,1); build(root,1,cnt); scanf("%d",&m); for (int i=1;i<=m;i++) { scanf("%s",s); if (s[0]=='C') { scanf("%d%d",&x,&y); int u,v; u=eg[x].u;v=eg[x].v; if (fath[u]==v) modify(root,1,cnt,w[u],w[u],y,1); else modify(root,1,cnt,w[v],w[v],y,1); } else work(); } return 0; }