Title Address: Spoj 375
Tree chain split first!
Really is a seemingly very high-level data structure, in fact, the tree's edge from the tree structure into a linear structure, so you can use a segment tree or a tree array and other data structures for rapid maintenance. The time is reduced to N*log (2*n).
This problem is maintained with the line tree.
The code is as follows:
#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace STD;#define LL Long Long#define PI ACOs ( -1.0)//#pragma comment (linker, "/stack:1024000000")Const intMod=1e9+7;Const intinf=0x3f3f3f3f;Const Doubleeqs=1e-3;Const intmaxn=10000+Ten;#define Root 1, N, 1#define Lson L, Mid, rt<<1#define Rson mid+1, R, Rt<<1|1intmax[maxn<<2], HEAD[MAXN], CNT, n;intSIZ[MAXN], DEP[MAXN], W[MAXN], TOP[MAXN], SON[MAXN], FA[MAXN], tot;structnode{intU, V, W, next;} edge[maxn<<1];voidAddintUintVintW) {edge[cnt].u=u; Edge[cnt].v=v; Edge[cnt].w=w; Edge[cnt].next=head[u]; head[u]=cnt++;}voidInit () {memset(head,-1,sizeof(head)); Cnt=0;memset(DEP,0,sizeof(DEP));memset(Son,0,sizeof(son));memset(Max,0,sizeof(Max)); tot=0;}voidDFS1 (intUintP) {siz[u]=1; for(inti=head[u];i!=-1; i=edge[i].next) {intV=EDGE[I].V;if(v==p)Continue; dep[v]=dep[u]+1; DFS1 (V,u); Fa[v]=u;if(Siz[v]>siz[son[u]]) son[u]=v; SIZ[U]+=SIZ[V]; }}voidDFS2 (intUintTP) {w[u]=++tot; top[u]=tp;if(Son[u]) DFS2 (Son[u],top[u]); for(inti=head[u];i!=-1; i=edge[i].next) {intV=EDGE[I].V;if(V!=son[u]&&v!=fa[u]) DFS2 (V,V); }}structline_tree{voidPushup (intRT) {Max[rt]=max (max[rt<<1],max[rt<<1|1]); }voidUpdate (intPintXintLintRintRT) {if(L==R) {max[rt]=x;return; }intMid=l+r>>1;if(P<=mid) Update (P,x,lson);ElseUpdate (P,x,rson); Pushup (RT); }intQuery (intllintRrintLintRintRT) {if(LL<=L&&RR>=R) {returnMAX[RT]; }intMid=l+r>>1, ans=0;if(Ll<=mid) Ans=max (Query (Ll,rr,lson), ans);if(Rr>mid) Ans=max (Ans,query (Ll,rr,rson));returnAns }}lt;intQuery (intUintV) {intF1=top[u], F2=top[v], ans=0; while(F1!=F2) {if(Dep[f1]<dep[f2]) {swap (U,V); Swap (F1,F2); } Ans=max (Ans,lt. Query (W[f1],w[u],root)); U=fa[f1];f1=top[u]; }if(U==V)returnAnsif(Dep[u]<dep[v]) swap (U,V);returnMax (ans,lt. Query (W[son[v]],w[u],root));}intMain () {intM, q, I, U, V, T, X, C;Chars[Ten];scanf("%d", &t); while(t--) {scanf("%d", &n); Init (); for(i=1; i<n;i++) {scanf("%d%d%d", &u,&v,&c); Add (U,V,C); Add (V,U,C); } DFS1 (1,-1); DFS2 (1,1); for(i=0; i<cnt;i+=2) {u=edge[i].u; V=EDGE[I].V;if(Dep[u]<dep[v]) swap (U,V); Lt. Update (W[u],edge[i].w,root); } while(scanf('%s ', s)!=eof&&s[0]!=' D '){if(s[0]==' C '){scanf("%d%d", &x,&c); u=edge[x-1<<1].u; v=edge[x-1<<1].V;if(Dep[u]<dep[v]) swap (U,V); Lt. Update (W[u],c,root); }Else{scanf("%d%d", &u,&v);printf("%d\n", Query (u,v)); } } }return 0;}
SPOJ 375 Qtree Series-query on a tree (chain split)