Description
N points, form a tree structure. There are M times issuing, selecting two points each x, y
for the x-y path (including x, y) of each point sent a bag Z types of items. Completion of
all the issued, each point store up to what kind of items.
Input
The first row of numbers N, M
the next N-1 lines of two numbers a, b, indicates there is an edge between a and b,
then the next M rows, each row of three numbers x, y, z. If that
Output
There are N rows of the output
digital representation for each row i of the i th point is stored items which most, if there is
the same number of a variety of articles, the minimum output number. If an item does not point
output 0
See the tree path to operate (in konjac blogger current level of knowledge) is nothing more than two choices, sectional tree / tree differential
But in the end asked only once if the difference chapter is a better choice
And we want to operate not only the right to make changes to the value of the point, but the insertion of the new weights for each point and count the number of outstanding
This time should expect the right to build value for each segment tree node to maintain information
Such differential operation on the use of weights segment tree insert operation to solve
However, when the geese in the final statistical information to be merged subtree
So it needs to merge tree line
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int N=100005; int n,m,to[N<<1],nxt[N<<1],head[N],tot=0; int size[N*50],type,root[N],ls[N*50],rs[N*50],fa[N][22],dep[N],now[N*50],ans[N]; void add(int x,int y) { to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void dfs(int x,int deep) { dep[x]=deep; for(int i=1;i<=20;i++) four [x] [c] = four [four [x] [p 1 ]] [p 1 ]; for ( int on = Head [x]; in; at = nxt [c]) { if(dep[to[i]])continue; fa[to[i]][0]=x; dfs(to[i],deep+1); } } int lca(int x,int y) { if(dep[x]>dep[y])swap(x,y); for(int i=20;i>=0;i--) if(dep[fa[y][i]]>=dep[x])y=fa[y][i]; if(x==y)return x; for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } void up(int x) { if(size[ls[x]]>=size[rs[x]]) { size[x]=size[ls[x]]; now[x]=now[ls[x]]; } else { size[x]=size[rs[x]]; now[x]=now[rs[x]]; } } void add(int &k,int l,int r,int val,int num) { if(!k)k=++type; if(l==r) { size[k]+=num; now[k]=l; return ; } int mid=l+r>>1; if(val<=mid)add(ls[k],l,mid,val,num); else add(rs[k],mid+1,r,val,num); up(k); return ; } you Merge ( you get, you y, you're with, you r) { if(!x||!y)return x+y; if(l==r) { size[x]=size[x]+size[y]; now[x]=l; return x; } int mid=l+r>>1; ls[x]=Merge(ls[x],ls[y],l,mid); rs[x]=Merge(rs[x],rs[y],mid+1,r); up(x); return x; } void cacl(int x) { for(int i=head[x];i;i=nxt[i]) { if(to[i]==fa[x][0])continue; cacl(to[i]); root[x]=Merge(root[x],root[to[i]],1,N-5); } if(now[root[x]])ans[x]=now[root[x]]; else ans[x]=0; } int main () { n=read();m=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); add(x,y);add(y,x); } dfs(1,1); for(int i=1;i<=m;i++) { int x=read(),y=read(),z=read(); int LCA=lca(x,y);//cout<<"///"<<LCA<<endl; add(root[x],1,N-5,z,1); add(root[y],1,N-5,z,1); add(root[LCA],1,N-5,z,-1); add(root[fa[LCA][0]],1,N-5,z,-1); } cacl(1); for(int i=1;i<=n;i++)printf("%d\n",ans[i]); return 0; }