SPOJ-QTREE Query on a tree 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - SPOJ-QTREE
题意概括
给你一颗树,每两点之间有权值,然后改变一些权值,问一条路径上的最大值。
题解
树链剖分裸题。
代码
#include <cstring> #include <algorithm> #include <cstdio> #include <cmath> #include <cstdlib> using namespace std; const int N=10005; struct Edge{ int cnt,y[N*2],z[N*2],nxt[N*2],fst[N]; void clear(){ cnt=0; memset(fst,0,sizeof fst); } void add(int a,int b,int c){ y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt; } }g; struct edge{ int a,b,c; }e[N]; int T,n,pos; int fa[N],fadis[N],size[N],depth[N],son[N],top[N],p[N],ap[N]; int maxv[N*4]; void Get_Gen_Info(int rt,int pre,int d){ depth[rt]=d,fa[rt]=pre,size[rt]=1,son[rt]=-1; for (int i=g.fst[rt];i;i=g.nxt[i]) if (g.y[i]!=pre){ int s=g.y[i]; fadis[s]=g.z[i]; Get_Gen_Info(s,rt,d+1); size[rt]+=size[s]; if (son[rt]==-1||size[s]>size[son[rt]]) son[rt]=s; } } void Get_Pos(int rt,int tp){ top[rt]=tp; if (son[rt]==-1){ p[rt]=++pos,ap[pos]=rt; return; } else { p[rt]=++pos,ap[pos]=rt; Get_Pos(son[rt],tp); } for (int i=g.fst[rt];i;i=g.nxt[i]){ int s=g.y[i]; if (s!=fa[rt]&&s!=son[rt]) Get_Pos(s,s); } } void pushup(int rt){ maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]); } void build(int rt,int le,int ri){ if (le==ri){ maxv[rt]=fadis[ap[le]]; return; } int mid=(le+ri)>>1; build(rt<<1,le,mid); build(rt<<1|1,mid+1,ri); pushup(rt); } void change(int rt,int le,int ri,int pos,int v){ if (le==ri){ maxv[rt]=v; return; } int mid=(le+ri)>>1; if (pos<=mid) change(rt<<1,le,mid,pos,v); else change(rt<<1|1,mid+1,ri,pos,v); pushup(rt); } int query(int rt,int le,int ri,int xle,int xri){ if (ri<xle||le>xri) return 0; if (xle<=le&&ri<=xri) return maxv[rt]; int mid=(le+ri)>>1; return max(query(rt<<1,le,mid,xle,xri),query(rt<<1|1,mid+1,ri,xle,xri)); } int find(int a,int b){ int f1=top[a],f2=top[b],ans=0; while (f1!=f2){ if (depth[f1]<depth[f2]) swap(f1,f2),swap(a,b); ans=max(ans,query(1,1,n,p[f1],p[a])); a=fa[f1],f1=top[a]; } if (a==b) return ans; if (depth[a]>depth[b]) swap(a,b); return max(ans,query(1,1,n,p[son[a]],p[b])); } int main(){ scanf("%d",&T); while (T--){ g.clear(); scanf("%d",&n); for (int i=1,a,b,c;i<n;i++){ scanf("%d%d%d",&a,&b,&c); e[i].a=a,e[i].b=b,e[i].c=c; g.add(a,b,c); g.add(b,a,c); } pos=0,fadis[1]=0; Get_Gen_Info(1,0,0); Get_Pos(1,1); for (int i=1;i<n;i++) if (depth[e[i].a]>depth[e[i].b]) swap(e[i].a,e[i].b); build(1,1,n); char str[10]; while (scanf("%s",str)){ if (str[0]=='D') break; int a,b; scanf("%d%d",&a,&b); if (str[0]=='Q') printf("%d\n",find(a,b)); else change(1,1,n,p[e[a].b],b); } } return 0; }