[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
",b[id[r[i]]]);
94 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11834550.html