The tree is mapped on a line segment and then each heavy chain becomes a continuous interval.
#include <iostream>#include<cstdio>#include<string.h>#include<vector>#include<algorithm>#pragmaComment (linker, "/stack:10240000,10240000")using namespacestd;Const intmaxn=100005; Vector<int>F[MAXN];intSon[maxn],num[maxn],fa[maxn],top[maxn],p[maxn],fp[maxn],pos,depth[maxn],ans[maxn];vector<int>P[MAXN];intloc,v;structsegmentitree{intnum[maxn*4],id[maxn*4]; voidBuildintOintLintR) {Num[o]=0; Id[o]=0; if(l>=R) {Num[o]=0; id[o]=L; return ; } intMid = (l+r)/2; Build (o*2, L,mid); Build (o*2+1, mid+1, R); } voidMaintain (into) {Num[o]=0; Id[o]=0; if(num[o*2]==0&&num[o*2+1]==0)return; if(num[o*2] >= num[o*2+1]) {Num[o]=num[o*2]; Id[o]=id[o*2]; } Else{Num[o]=num[o*2+1]; Id[o]=id[o*2+1]; } } voidAddintOintLintR) { if(l>=s) {Num[o]+=v; return ; } intMid = (l+r) >>1; if(loc<=mid) {Add (o*2, L,mid); }Else{Add (o*2+1, mid+1, R); } maintain (o); }}t;voidIntiintN) { for(intI=0; i<=n+2; ++i) f[i].clear (), p[i].clear (); POS=0;}voidDfsintCurintPerintDEP) {Depth[cur]=DEP; Son[cur]=-1; Fa[cur]=per; Num[cur]=1; intlen=f[cur].size (); for(intI=0; i<len; ++i) { intto =F[cur][i]; if(To==per)Continue; DFS (TO,CUR,DEP+1); Num[cur]+=Num[to]; if(son[cur] = =-1|| num[Son[cur]]< num[to]) son[cur]=to ; }}voidFinde (intCur,intPerintxx) {Top[cur]=xx; POS++; P[cur]=POS; Fp[pos]=cur; if(son[cur]!=-1) Finde (SON[CUR],CUR,XX); intLen =f[cur].size (); for(intI=0; I<len; + +i) { intto=F[cur][i]; if(to==per| | To==son[cur])Continue; Finde (to,cur,to); }}voidSolveintXintYintd) { intF1=top[x],f2=Top[y]; while(f1!=F2) { if(depth[f1]<Depth[f2]) { inttemp = x; X=y; y=temp; Temp=F1; F1=F2; F2=temp; } p[P[f1]].push_back (d); p[P[x]+1].push_back (-d); X=FA[F1]; F1=Top[x]; } if(depth[x]>Depth[y]) { inttemp = x; x = y; y=temp; } p[p[x]].push_back (d); P[p[y]+1].push_back (-d);}intMain () {intn,m; for(;;) {scanf ("%d%d",&n,&m); if(n==0&&m==0) Break; Inti (n); for(intI=1; I<n; + +i) { intb; scanf ("%d%d",&a,&b); F[a].push_back (b); F[b].push_back (a); } DFS (1,0,0); Finde (1,0,1); intn=0; for(intI=0; i<m; ++i) { inta,b,d; scanf ("%d%d%d",&a,&b,&d); Solve (A,B,D); N=Max (d,n); } memset (ans,0,sizeof(ans)); if(n!=0) {T.build (1,1, N); for(intI=1; i<=n; ++i) { intL =p[i].size (); for(intj=0; j<l; ++j) { intto=P[i][j]; if(to>0) {v=1; Loc=to ; }Else{v=-1; Loc=-to ; } t.add (1,1, N); } if(t.num[1]!=0) Ans[fp[i]]=t.id[1]; Elseans[fp[i]]=0; } } for(intI=1; i<=n; ++i) printf ("%d\n", Ans[i]); } return 0;}
View Code
hdu5029 Tree chain split + segment tree