1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| const int MAXN=1e5+10; int N,Q,Idx,MaxCol; struct ST { int lc,rc,val,cnt; }Tr[MAXN*100]; inline void extend(int p1,int p2) { Tr[p1].val=Tr[p2].val,Tr[p1].cnt=Tr[p2].cnt; } inline void pushUp(int p) { if(Tr[Tr[p].lc].cnt>Tr[Tr[p].rc].cnt) extend(p,Tr[p].lc); else if(Tr[Tr[p].lc].cnt<Tr[Tr[p].rc].cnt) extend(p,Tr[p].rc); else if(Tr[Tr[p].lc].val<Tr[Tr[p].rc].val) extend(p,Tr[p].lc); else extend(p,Tr[p].rc); } void modifyX(int &p,int c,int v,int l,int r) { if(!p) p=++Idx; if(l==r) { Tr[p].cnt+=v,Tr[p].val=c; return ; } int mid=(l+r)>>1; if(c<=mid) modifyX(Tr[p].lc,c,v,l,mid); else modifyX(Tr[p].rc,c,v,mid+1,r); pushUp(p); } int merge(int p1,int p2,int l,int r) { if(!p1) return p2; if(!p2) return p1; if(l==r) { Tr[p1].cnt+=Tr[p2].cnt; return p1; } int mid=(l+r)>>1; Tr[p1].lc=merge(Tr[p1].lc,Tr[p2].lc,l,mid), Tr[p1].rc=merge(Tr[p1].rc,Tr[p2].rc,mid+1,r); pushUp(p1); return p1; } struct G { int next,to; }Edge[MAXN<<1]; int Head[MAXN],Total; inline void addEdge(int u,int v) { Edge[++Total]=(G){Head[u],v};Head[u]=Total; Edge[++Total]=(G){Head[v],u};Head[v]=Total; } int Fa[MAXN],Siz[MAXN],Dep[MAXN],Son[MAXN]; void dfsTree(int x,int last) { Fa[x]=last,Dep[x]=Dep[last]+1,Siz[x]=1; for(int e=Head[x],v;e;e=Edge[e].next) { if((v=Edge[e].to)==last) continue; dfsTree(v,x); Siz[x]+=Siz[v]; if(!Son[x]||Siz[v]>Siz[Son[x]]) Son[x]=v; } } int Top[MAXN],ans[MAXN],Rt[MAXN]; void dfsChain(int x,int topf) { Top[x]=topf; if(!Son[x]) return ; dfsChain(Son[x],topf); for(int e=Head[x],v;e;e=Edge[e].next) { if((v=Edge[e].to)==Fa[x]||v==Son[x]) continue; dfsChain(v,v); } } inline int getLca(int x,int y) { while(Top[x]!=Top[y]) { if(Dep[Top[x]]<Dep[Top[y]]) std::swap(x,y); x=Fa[Top[x]]; } return Dep[x]>Dep[y]?y:x; } std::vector<std::pair<int,int>>Modify[MAXN]; void reDfs(int x,int last) { for(int e=Head[x],v;e;e=Edge[e].next) { if((v=Edge[e].to)==last) continue; reDfs(v,x); Rt[x]=merge(Rt[x],Rt[v],0,MaxCol); } for(auto i:Modify[x]) modifyX(Rt[x],i.first,i.second,0,MaxCol); ans[x]=Tr[Rt[x]].val; } int main() { read(N,Q);Rt[1]=1,Idx=N; for(int i=2,u,v;i<=N;++i) { read(u,v);addEdge(u,v); Rt[i]=i; } dfsTree(1,0),dfsChain(1,1); for(int u,v,c;Q--;) { read(u,v,c);checkMax(MaxCol,c); int o=getLca(u,v); Modify[u].push_back({c,1}),Modify[v].push_back({c,1}); Modify[o].push_back({c,-1}),Modify[Fa[o]].push_back({c,-1}); } reDfs(1,-1); for(int i=1;i<=N;++i) write(ans[i],'\n'); return 0; }
|