#include <iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<map>#include<Set>#include<vector>#include<cstdio>using namespacestd;Const intmaxn=10010;structedge{intTo,next;} EDGE[MAXN*2];intHead[maxn],tot;intTOP[MAXN];//Top[v] Represents the top node of the heavy chain where V is locatedintFA[MAXN];//Father NodeintDEEP[MAXN];//DepthintNUM[MAXN];//Num[v] Indicates the number of nodes of a subtree with V as its rootintP[MAXN];//P[v] represents the position of V and its parent node in the segment treeintFP[MAXN];//opposite the P arrayintSON[MAXN];//Heavy sonintPos;voidinit () {tot=0; memset (Head,-1,sizeof(head)); POS=0; memset (son,-1,sizeof(son));voidAddedge (intUintv) {edge[tot].to=v; Edge[tot].next=Head[u]; Head[u]=tot++;}voidDFS1 (intUintPreintD//The first time DFS Fa,deep,num,son{Deep[u]=D; Fa[u]=Pre; Num[u]=1; for(intI=head[u]; i!=-1; I=Edge[i].next) { intv=edge[i].to; if(v!=pre) {DFS1 (v,u,d+1); Num[u]+=Num[v]; if(son[u]==-1|| Num[v]>num[son[u]]) son[u]=v; } }}voidGetPosintUintSp//The second time DFS find top and P{Top[u]=sp; if(son[u]!=-1) {P[u]=pos++; Fp[p[u]]=T; GetPos (SON[U],SP); } Else{P[u]=pos++; Fp[p[u]]=u; return; } for(intI=head[u]; i!=-1; I=Edge[i].next) { intv=edge[i].to; if(v!=son[u]&&v!=Fa[u]) GetPos (V,V); }}//Segment Treestructnode{intL,r,max;} SEGTREE[MAXN*3];voidBuildintIintLintR) {SEGTREE[I].L=M; SEGTREE[I].R=R; Segtree[i]. Max=0; if(L==R)return; intMid= (L+R)/2; Build (I<<1, L,mid); Build ((I<<1)|1, mid+1, R);}voidPUSH_UP (inti) {Segtree[i]. Max=max (segtree[i<<1]. max,segtree[(i<<1)|1]. Max);}voidUpdateintIintKintVal//the K value of the update segment tree is Val{ if(segtree[i].l==k&&segtree[i].r==k) {Segtree[i]. Max=Val; return; } intMid= (SEGTREE[I].L+SEGTREE[I].R)/2; if(k<=mid) Update (i<<1, K,val); ElseUpdate ((i<<1)|1, K,val); PUSH_UP (i);}intQueryintIintLintR//Query the maximum value of [L,r] in the segment tree{ if(SEGTREE[I].L==L&&SEGTREE[I].R==R)returnSegtree[i]. Max; intMid= (SEGTREE[I].L+SEGTREE[I].R)/2; if(R<=mid)returnQuery (i<<1, L,r); Else if(L>mid)returnQuery ((i<<1)|1, L,r); Else returnMax (Query (i<<1, L,mid), query (i<<1)|1, mid+1, R));}intFindintUintV//Query The maximum value of the u->v edge{ intf1=top[u],f2=top[v],tmp=0; while(f1!=F2) { if(deep[f1]<Deep[f2]) {swap (F1,F2); Swap (U,V); } tmp=max (Tmp,query (1, P[f1],p[u])); U=FA[F1]; F1=Top[u]; } if(U==V)returntmp; if(deep[u]>Deep[v]) swap (U,V); returnMax (Tmp,query (1, P[son[u]],p[v]));}inte[maxn][3];intMain () {//freopen ("In.txt", "R", stdin); intT,n; scanf ("%d",&t); while(t--) {init (); scanf ("%d",&N); for(intI=0; i<n-1; i++) {scanf ("%d%d%d", &e[i][0],&e[i][1],&e[i][2]); Addedge (e[i][0],e[i][1]); Addedge (e[i][1],e[i][0]); } DFS1 (1,0,0); GetPos (1,1); Build (1,0, pos-1); for(intI=0; i<n-1; i++) { if(deep[e[i][0]]>deep[e[i][1]]) Swap (e[i][0],e[i][1]); Update (1, p[e[i][1]],e[i][2]); } Charop[Ten]; intu,v; while(SCANF ("%s", op)) { if(op[0]=='D') Break; scanf ("%d%d",&u,&v); if(op[0]=='Q') printf ("%d\n", find (u,v));//Query The maximum value of the top-right of the u->v path ElseUpdate1, p[e[u-1][1]],V);//Modify the length of the U-Bar to v } } return 0;}
spoj375 Query on a trees (tree-chain-split entry)