you will get a containing n nodes of a tree . number of tree nodes from 1 to ? . Each node has an integer weight.
We will ask you to do the following:
- UVK: asks the K minimum weights on the path from node U to Node v
input
There are two integers in the first row ? and medium . (n,m <= 100000)
in the second row, there is n an integer. The first integer represents the weight of the I-node.
in the next N-1 Row, each row contains two integers u v, which describes an edge (u,v).
in the next in M rows, each row contains three integer U-v k, which means the operation of the K-min weights on the path from node u to node V is required .
Problem Solving Ideas:
First of all, we can use the Chairman tree to make a small problem, no problem,
But for a tree structure, we need to convert it to linear, and then we need a tree profile to do it.
Then consider how the K value on the chain is maintained,
Found out that if the tree was cut, it couldn't be maintained.
Because the road (U,V) may be on a number of chains, then you can not ask for each k value, so obviously wrong ah,
And then we know that the Chairman tree is actually maintaining a prefix and
Then we can prefix each node to the root node and can find the K value of any node to the root node,
So, according to the nature of the Chairman tree, we can calculate the K value on the Way (U,V).
Just a little bit of a change at the time of the query.
sum[ls[u]]+sum[ls[v]]-sum[ls[lca(u,v)]]-sum[ls[fa[lca(u,v)]]];
#include <iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<map>#include<bits/stdc++.h>using namespacestd;Const intN = 1e5+ -; typedefLong LongLL;intrt[n* -], ls[n* -], rs[n* -], sum[n* -];intfa[2*n][ -], dep[2*N], vis[n];intA[n], b[n], tot, CNT, head[n], Len;structnode{intto, next;} p[2*N];voidinit () {memset (head,-1,sizeof(head)); memset (Vis,0,sizeof(VIS)); CNT=0; return ;}voidAddintUintv) {p[cnt].to=v,p[cnt].next=head[u];head[u]=cnt++; P[cnt].to=u,p[cnt].next=head[v];head[v]=cnt++; return ;}voidBuildint&o,intLintR) {o= ++tot,sum[o]=0; if(L==R)return ; intMid= (L+R)/2; Build (Ls[o],l,mid); Build (Rs[o],mid+1, R); return ;}voidUpdateint&o,intLintRintLastintp) {o= ++tot; Ls[o]=ls[last],rs[o]=Rs[last]; Sum[o]=sum[last]+1; if(L==R)return ; intMid= (L+R)/2; if(p<=mid) Update (LS[O],L,MID,LS[LAST],P); ElseUpdate (rs[o],mid+1, r,rs[last],p); return ;}intQueryintSsintTtintS1,intT1,intLintRintCNT) { if(L==R)returnl; inttmp=sum[ls[tt]]+sum[ls[ss]]-sum[ls[s1]]-Sum[ls[t1]]; intMid= (L+R)/2; if(tmp>=cnt)returnquery (LS[SS],LS[TT],LS[S1],LS[T1],L,MID,CNT); Else returnQuery (rs[ss],rs[tt],rs[s1],rs[t1],mid+1, r,cnt-tmp);}voidDfsintUintDintFintroot) {Vis[u]=1, dep[u]=d,fa[u][0]=F; Update (Rt[u],1, Len,root,a[u]); Root=Rt[u]; for(inti=head[u];i!=-1; i=P[i].next) { intv=p[i].to; if(Vis[v])Continue; DFS (V,d+1, U,root); } return ;}voidLcaintN) { intK= (int) (Log (1.0*n)/log (2.0)); for(intI=1; i<=k;i++) { for(intj=1; j<=n;j++) {Fa[j][i]=fa[fa[j][i-1]][i-1]; } } return ;}int Get(intXintYintN) { if(dep[x]<Dep[y]) swap (x, y); intK= (int) (Log (1.0*n)/log (2.0)); intd=dep[x]-Dep[y]; for(intI=0; i<=k;i++) if((d& (1<<i)) x=Fa[x][i]; if(x==y)returnx; for(inti=k;i>=0; i--) { if(Fa[x][i]!=fa[y][i]) x=fa[x][i],y=Fa[y][i]; } returnfa[x][0];} intMain () {intT, N, Q; scanf ("%d%d", &n, &q); for(intI=1; i<=n; i++) scanf ("%d", &a[i]), b[i]=A[i]; Sort (b+1, b+n+1); Len=unique (b +1, b+n+1)-(b +1); Tot=0; Build (rt[0],1, Len); for(intI=1; i<=n; i++) A[i]=lower_bound (b +1, b+len+1, A[i])-(b); Init (); for(intI=0; i<n-1; i++) { intx, y; scanf ("%d%d", &x, &y); Add (x, y); } DFS (1,1,0, rt[0]); LCA (n); while(q--) { intL, R, X; scanf (" %d%d%d", &l, &r, &x); intpos=Get(L,r,n); printf ("%d\n", B[query (rt[l],rt[r],rt[pos],rt[fa[pos][0]],1, Len,x)]); } return 0;}
View Code
Spoj Cot-count on a tree (chairman trees +lca, Tree K-Large)