线段树合并

其实这个模板题高于板子

其实就是对应点相加
主要是理解每种颜色一颗节点的思想
线段树合并

线段树合并往往是为了更好的统计答案,思路是从下往上的.

#include<bits/stdc++.h>
#define int long long
#define F(i,i0,n) for(int i=i0;i<=n;i++)
using namespace std;
inline int rd(){
    int f=0,x=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return f?-x:x;
}
const int N=5e6+5,M=2e5+7;
struct Id{
    int u,v,nt;
}e[M];
int p[N],id;
void add(int x,int y){e[++id]={x,y,p[x]};p[x]=id;}
int n,m;
int dep[N],dis[N],fa[N][25];
void dfs(int x,int ffa){
    fa[x][0]=ffa;
    dep[x]=dep[ffa]+1;
    F(i,1,__lg(dep[x]))fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int i=p[x];i;i=e[i].nt){
        int v=e[i].v;
        if(v==ffa)continue;
        dfs(v,x);
    }
}
int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    int d=dep[x]-dep[y];
    for(int i=20;i>=0;i--)if(d&(1<<i))x=fa[x][i];
    if(x==y)return x;
    for(int i=20;i>=0;i--){
        if(fa[x][i]!=fa[y][i]){
            x=fa[x][i];
            y=fa[y][i];
        }
    }
    return x=fa[x][0];
}
struct Seg{
    int ls,rs;
    int maxn,clo;
    #define ls(p) tr[p].ls
    #define rs(p) tr[p].rs
    #define mid (l+r>>1)
}tr[N<<2];
int rot[N],nod;
int Rmax;
void pushup(int p){
    if(tr[ls(p)].maxn>=tr[rs(p)].maxn)
        tr[p].maxn=tr[ls(p)].maxn,tr[p].clo=tr[ls(p)].clo;
    else tr[p].maxn=tr[rs(p)].maxn,tr[p].clo=tr[rs(p)].clo;
}
void update(int &p,int nx,int k,int l=1,int r=Rmax){
    if(!p)p=++nod;
    if(l==r){
        tr[p].maxn+=k;
        tr[p].clo=nx;
        return;
    }
    if(nx<=mid)update(ls(p),nx,k,l,mid);
    if(mid<nx)update(rs(p),nx,k,mid+1,r);
    pushup(p);
}
void merge(int &p1,int &p2,int &p,int l=1,int r=Rmax){
    if(!p1||!p2){p=p1|p2;return ;}
    p=++nod;
    if(l==r){
        tr[p].maxn=tr[p1].maxn+tr[p2].maxn;
        tr[p].clo=l;
        return ;
    }
    merge(tr[p1].ls,tr[p2].ls,tr[p].ls,l,mid);
    merge(tr[p1].rs,tr[p2].rs,tr[p].rs,mid+1,r);
    pushup(p);
}
struct Qus{
    int x,y,z;
}q[N]; 
int ans[N];
void ans_dfs(int x){
    for(int i=p[x];i;i=e[i].nt){
        int v=e[i].v;
        if(v==fa[x][0])continue;
        ans_dfs(v);
        int tmprot;
        merge(rot[v],rot[x],tmprot);
        rot[x]=tmprot;
    }
    if(tr[rot[x]].maxn)ans[x]=tr[rot[x]].clo;
}
signed main(){
    n=rd(),m=rd();
    F(i,1,n-1){
        int x=rd(),y=rd();
        add(x,y);
        add(y,x);
    }
    dfs(1,0);
    F(i,1,m){
        q[i].x=rd(),q[i].y=rd(),q[i].z=rd();
        Rmax=max(Rmax,q[i].z);
    }
    F(i,1,m){
        int ffa=lca(q[i].x,q[i].y);
        update(rot[fa[ffa][0]],q[i].z,-1);
        update(rot[q[i].x],q[i].z,1);
        update(rot[q[i].y],q[i].z,1);
        update(rot[ffa],q[i].z,-1);
    }
    ans_dfs(1);
    F(i,1,n)cout<<ans[i]<<"\n";
    return 0;
}
posted @ 2023-09-09 17:10  ussumer  阅读(20)  评论(0)    收藏  举报