随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

 

线段树合并板子

 

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
#include<iostream>
#include<cstring>
using namespace std;
const int N =5e5+10,M =N*2;
 
int nxt[M],hd[N],all=1,go[M],n,m;
 int dep[N],f[N][22],father[N];
  
 void add_(int x,int y){
     go[++all]=y,nxt[all]=hd[x],hd[x]=all;
 }
  
  void init(int x,int fa){
     int i,y;
     dep[x]=dep[fa]+1;
     f[x][0]=fa; father[x]=fa;
      
     for(i=0;i<=19;i++) f[x][i+1]=f[f[x][i]][i];
      
     for(i=hd[x];i;i=nxt[i]){
         y=go[i]; if(y==fa) continue;
         init(y,x);
     }
 }
 int lca(int x,int y){
     int i;
     if(dep[x]<dep[y]) swap(x,y);
      
     for(i=19;i>=0;i--){
         if(dep[f[x][i]]>=dep[y]) x=f[x][i];
     }
     if(x==y) return x;
      
     for(i=19;i>=0;i--){
         if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
     }
     return f[x][0];
 }
  
 int rt[N] ;
 int pool=0;
 int New(){  return ++pool;  }
 int sum[N*20],maxp[N*20],ls[N*20],rs[N*20];
  
 void up(int k){
    if(sum[ls[k]]>=sum[rs[k]])
        sum[k]=sum[ls[k]],maxp[k]=maxp[ls[k]];
    else
        sum[k]=sum[rs[k]],maxp[k]=maxp[rs[k]];
}
 int change(int k,int l,int r,int x,int v){
    if(k==0) k=New();
     
    if(l==r){
        sum[k]+=v;
        maxp[k]=x; return k;
    }
    int md=(l+r)>>1;
    if(x<=md) ls[k]=change(ls[k],l,md,x,v);
    else rs[k]=change(rs[k],md+1,r,x,v) ;
     
    up(k);
    return k;
 }
 int merge(int a,int b,int l,int r){
    if (a==0||b==0)
         return a|b;
     
    if(l==r){
        sum[a]+=sum[b]; maxp[a]=l; return a;
    }
     
    int md=(l+r)>>1;
    ls[a]=merge(ls[a],ls[b],l,md) ;
    rs[a]=merge(rs[a],rs[b],md+1,r);
    up(a);
    return a;
 }
 int ans[N] ;
  
 void dfs(int x){
    for(int i=hd[x];i;i=nxt[i]){
        int y =go[i] ; if(y==father[x]) continue ;
        dfs(y);
        rt[x]=merge(rt[x],rt[y],1,1e5) ;
    }
    ans[x] = sum[rt[x]]>0 ?maxp[rt[x]]: 0 ;
 }
 signed main(){
    cin>>n>>m;
    for(int i=1,x,y;i<n;i++) cin>>x>>y,add_(x,y),add_(y,x);
    init(1,0) ;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z; int t =lca(x,y) ;
        rt[x]=change(rt[x],1,1e5,z,1) ;
        rt[y]=change(rt[y],1,1e5,z,1) ;
        rt[t]=change(rt[t],1,1e5,z,-1);
        rt[father[t]]=change(rt[father[t]],1,1e5,z,-1);
    }
    dfs(1) ;
     
    for(int i=1;i<=n;++i) cout << ans[i] <<endl;
 }

 

posted on   towboat  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示