线段树合并板子15pts求调
查看原帖
线段树合并板子15pts求调
209923
PRIMITIVE_LIGHTS楼主2024/11/21 22:52

RT

#include<iostream>
#include<vector>
using namespace std;
const int N=1e5+1;
vector<int>debug[N];
int root[N]; int ls[N*15]; int rs[N*15];
int ct; int tr[N*15]; int col[N*15];
int ans[N];  int n,m;
void push_up(int k){ 
    if(tr[ls[k]]>=tr[rs[k]]) col[k]=col[ls[k]],tr[k]=tr[ls[k]];
    else col[k]=col[rs[k]],tr[k]=tr[rs[k]];
}
int modify(int l,int r,int k,int pos,int v){
    if(!k) k=++ct;
    if(l==r){tr[k]+=v; col[k]=l; return k;}
    int mid=(l+r)>>1;
    if(pos<=mid) ls[k]=modify(l,mid,ls[k],pos,v);
    else rs[k]=modify(mid+1,r,rs[k],pos,v);
    push_up(k);
    return k;
}
int merge(int l,int r,int k1,int k2){
    if(!k1||!k2) return k1+k2;
    if(l==r){
        tr[k1]+=tr[k2]; 
        if(tr[k1])col[k1]=l; 
        else col[k1]=0;
        return k1;
    }
    int mid=(l+r)>>1;
    ls[k1]=merge(l,mid,ls[k1],ls[k2]);
    rs[k1]=merge(mid+1,r,rs[k1],rs[k2]);
    push_up(k1);
    return k1;
}
int query(int l,int r,int k,int pos){
    if(l==r){return tr[k];}
    int mid=(l+r)>>1;
    if(pos<=mid) return query(l,mid,ls[k],pos);
    else return query(mid+1,r,rs[k],pos);
}
//lca
int fa[N]; int dep[N]; int top[N];
int cnt; int son[N]; int sz[N];
vector<int> e[N];
int dfs1(int t,int f){
    fa[t]=f; dep[t]=dep[f]+1; sz[t]=1;
    int mx=0;
    for(auto it:e[t]){
        if(it==f) continue; 
        sz[t]+=dfs1(it,t); 
        if(sz[it]>mx) mx=sz[it],son[t]=it;
    } return sz[t];
}
void dfs2(int t,int f){
    top[t]=f; 
    if(son[t]){
        dfs2(son[t],f);
        for(auto it:e[t])
            if(it!=fa[t]&&it!=son[t]) dfs2(it,it);
    }
}
int lca(int x,int  y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    return (dep[x]>dep[y])?y:x;
}
//
void dfs(int t){
    for(auto it:e[t])
        if(it!=fa[t]) dfs(it),merge(1,N,root[t],root[it]);
    ans[t]=col[root[t]];
}
int main(){ 
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n-1;++i){
        int a,b; cin>>a>>b;
        e[a].push_back(b); e[b].push_back(a);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(int i=1;i<=m;++i){
        int u,v,w;
        cin>>u>>v>>w;
        int l=lca(u,v);
        root[u]=modify(1,N,root[u],w,1);
        root[v]=modify(1,N,root[v],w,1);
        root[l]=modify(1,N,root[l],w,-1);
        if(fa[l]) root[fa[l]]=modify(1,N,root[fa[l]],w,-1);
    }
    dfs(1);
    for(int i=1;i<=n;++i){
        cout<<ans[i]<<endl;
    }
}

捞一下上次的 改了值域 现在15pts

2024/11/21 22:52
加载中...