[bzoj3307]雨天的尾巴
对每一个节点开一颗权值线段树维护打的标记(x+,y+,lca(x,y)-,fa[lca(x,y)]-),然后每一个节点将子树内所有节点(其实就是已经合并过的儿子)合并即可。
(毒瘤的是这道题需要将物品离散化一下否则会爆栈,当然也可以写bfs)
1 # pragma comment(linker, /STACK:102400000,102400000) 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define N 100005 5 #define mid (l+r>>1) 6 struct ji{ 7 int nex,to; 8 }edge[N<<1]; 9 struct ji2{ 10 int x,y,z; 11 }q[N]; 12 int E,n,m,x,y,z,head[N],a[N],b[N],in[N],out[N],f[N][21]; 13 int V,r[N],id[N*50],ls[N*50],rs[N*50],tr[N*50]; 14 bool cmp(ji2 x,ji2 y){ 15 return x.z<y.z; 16 } 17 void add(int x,int y){ 18 edge[E].nex=head[x]; 19 edge[E].to=y; 20 head[x]=E++; 21 } 22 bool pd(int x,int y){ 23 return (in[x]<=in[y])&&(out[y]<=out[x]); 24 } 25 int lca(int x,int y){ 26 if (pd(x,y))return x; 27 for(int i=20;i>=0;i--) 28 if (!pd(f[x][i],y))x=f[x][i]; 29 return f[x][0]; 30 } 31 void up(int k){ 32 tr[k]=max(tr[ls[k]],tr[rs[k]]); 33 if (tr[k]==tr[ls[k]])id[k]=id[ls[k]]; 34 else id[k]=id[rs[k]]; 35 } 36 void update(int &k,int l,int r,int x,int y){ 37 if (!k)k=++V; 38 if (l==r){ 39 tr[k]+=y; 40 id[k]=l; 41 return; 42 } 43 if (x<=mid)update(ls[k],l,mid,x,y); 44 else update(rs[k],mid+1,r,x,y); 45 up(k); 46 } 47 void merge(int &k1,int k2,int l,int r){ 48 if (k1*k2==0){ 49 k1+=k2; 50 return; 51 } 52 if (l==r){ 53 tr[k1]+=tr[k2]; 54 return; 55 } 56 merge(ls[k1],ls[k2],l,mid); 57 merge(rs[k1],rs[k2],mid+1,r); 58 up(k1); 59 } 60 void dfs(int k,int fa){ 61 in[k]=++x; 62 a[x]=k; 63 f[k][0]=fa; 64 for(int i=1;i<=20;i++)f[k][i]=f[f[k][i-1]][i-1]; 65 for(int i=head[k];i!=-1;i=edge[i].nex) 66 if (edge[i].to!=fa)dfs(edge[i].to,k); 67 out[k]=x; 68 } 69 int main(){ 70 scanf("%d%d",&n,&m); 71 memset(head,-1,sizeof(head)); 72 for(int i=1;i<n;i++){ 73 scanf("%d%d",&x,&y); 74 add(x,y); 75 add(y,x); 76 } 77 x=0; 78 dfs(1,1); 79 for(int i=1;i<=n;i++)r[i]=i; 80 V=n; 81 for(int i=1;i<=m;i++)scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z); 82 sort(q+1,q+m+1,cmp); 83 for(int i=1;i<=m;i++){ 84 x=q[i].x; 85 y=q[i].y; 86 if (q[i-1].z<q[i].z)b[++z]=q[i].z; 87 update(r[x],0,1e5,z,1); 88 update(r[y],0,1e5,z,1); 89 update(r[lca(x,y)],0,1e5,z,-1); 90 if (lca(x,y)>1)update(r[f[lca(x,y)][0]],0,1e5,z,-1); 91 } 92 for(int i=n;i>1;i--)merge(r[f[a[i]][0]],r[a[i]],0,1e5); 93 for(int i=1;i<=n;i++)printf("%d\n",b[id[r[i]]]); 94 }