两种显然的做法:
1.树上差分+线段树合并。$O(nlog n)$
2.树链剖分转为序列上差分+线段树。$O(nlog^2 n)$
后一种的代码:
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define ls (x<<1) 7 #define rs (ls|1) 8 #define lson ls,L,mid 9 #define rson rs,mid+1,R 10 #define mem(a) memset(a,0,sizeof(a)) 11 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 12 #define For(i,x) for (int i=h[x],k; i; i=nxt[i]) 13 typedef long long ll; 14 using namespace std; 15 16 const int N=100010; 17 int n,m,u,v,w,tim,cnt,id[N<<2],s[N<<2],to[N<<1],nxt[N<<1]; 18 int son[N],top[N],pos[N],d[N],sz[N],ans[N],fa[N],h[N]; 19 vector<int>V[N]; 20 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 21 void init(){ 22 cnt=0; tim=0; 23 rep(i,1,n) h[i]=son[i]=0,V[i].clear(); 24 } 25 26 void dfs1(int x){ 27 sz[x]=1; d[x]=d[fa[x]]+1; 28 For(i,x) if ((k=to[i])!=fa[x]){ 29 fa[k]=x; dfs1(k); sz[x]+=sz[k]; 30 if (sz[k]>sz[son[x]]) son[x]=k; 31 } 32 } 33 34 void dfs2(int x,int z){ 35 pos[x]=++tim; top[x]=z; 36 if (son[x]) dfs2(son[x],z); 37 For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k); 38 } 39 40 void work(int l,int r,int c){ V[l].push_back(c),V[r+1].push_back(-c); } 41 42 void solve(int u,int v,int c){ 43 for (; top[u]!=top[v]; u=fa[top[u]]){ 44 if (d[top[u]]<d[top[v]]) swap(u,v); 45 work(pos[top[u]],pos[u],c); 46 } 47 if (d[u]>d[v]) swap(u,v); 48 work(pos[u],pos[v],c); 49 } 50 51 void upd(int x){ 52 int k=s[ls]<s[rs] ? rs : ls; 53 s[x]=s[k]; id[x]=id[k]; 54 } 55 56 void build(int x,int L,int R){ 57 if (L==R){ s[x]=0; id[x]=L; return; } 58 int mid=(L+R)>>1; 59 build(lson); build(rson); upd(x); 60 } 61 62 void ins(int x,int L,int R,int pos,int k){ 63 if (L==R){ s[x]+=k; return; } 64 int mid=(L+R)>>1; 65 if (pos<=mid) ins(lson,pos,k); else ins(rson,pos,k); 66 upd(x); 67 } 68 69 int main(){ 70 freopen("hdu5029.in","r",stdin); 71 freopen("hdu5029.out","w",stdout); 72 while (scanf("%d%d",&n,&m)==2 && n+m){ 73 init(); int mx=0; 74 rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u); 75 fa[1]=0; dfs1(1); dfs2(1,1); 76 rep(i,1,m) scanf("%d%d%d",&u,&v,&w),solve(u,v,w),mx=max(mx,w); 77 build(1,0,mx); 78 rep(i,1,n){ 79 rep(j,0,(int)V[i].size()-1) 80 if (V[i][j]>0) ins(1,0,mx,V[i][j],1); else ins(1,0,mx,-V[i][j],-1); 81 ans[i]=id[1]; 82 } 83 rep(i,1,n) printf("%d ",ans[pos[i]]); 84 } 85 return 0; 86 }