• P4556 [Vani有约会]雨天的尾巴(线段树合并+lca)


    P4556 [Vani有约会]雨天的尾巴

    每个操作拆成4个进行树上差分,动态开点线段树维护每个点的操作。

    离线处理完向上合并就好了

    luogu倍增lca被卡了5分.....于是用rmq维护....

    常数很大,被bzoj卡了(但是我不想改了)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define ri register int
    using namespace std;
    int read(){
        char c=getchar(); int x=0;
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
        return x;
    }
    #define N 100001
    #define W 5000005
    int n,m,fa[N],fir[N],Log[N*2],f[18][N*2],tp,dfn[N],cc,ans[N];//一定记住st表的大小是n*2
    int u,rt[N],lc[W],rc[W],mx[W],id[W];
    vector <int> g[N];
    #define mid (l+r)/2
    void up(int o){
        mx[o]=id[o]=0;
        if(mx[lc[o]]>mx[o]) mx[o]=mx[lc[o]],id[o]=id[lc[o]];
        if(mx[rc[o]]>mx[o]) mx[o]=mx[rc[o]],id[o]=id[rc[o]];
    }
    void merge(int &o,int p,int l,int r){//线段树合并
        if(!o||!p){o=o+p; return;}
        if(l==r){mx[o]+=mx[p]; return;}
        merge(lc[o],lc[p],l,mid);
        merge(rc[o],rc[p],mid+1,r); up(o);
    }
    void ins(int &o,int l,int r,int k,int v){
        if(!o)o=++u;
        if(l==r){mx[o]+=v,id[o]=l; return;}
        if(k<=mid) ins(lc[o],l,mid,k,v);
        else ins(rc[o],mid+1,r,k,v);
        up(o);
    }
    void dfs(int x,int Fa){
        fa[x]=Fa; f[0][++tp]=dfn[++cc]=x; fir[x]=tp;
        for(int i=0;i<g[x].size();++i) if(g[x][i]!=Fa) dfs(g[x][i],x),f[0][++tp]=x;
    }
    inline int Min(int x,int y){return fir[x]<fir[y]?x:y;}
    int lca(int x,int y){
        ri l=fir[x],r=fir[y]; if(l>r) swap(l,r);
        ri k=Log[r-l+1];
        return Min(f[k][l],f[k][r-(1<<k)+1]);
    }
    int main(){
        n=read(); m=read(); int u,v,w,p;
        for(ri i=1;i<n;++i){
            u=read(),v=read();
            g[u].push_back(v);
            g[v].push_back(u);
        }dfs(1,0); Log[0]=-1;
        for(ri i=1;i<=tp;++i) Log[i]=Log[i>>1]+1;
        for(ri i=1;i<=Log[tp];++i)
            for(ri j=1;j+(1<<i)-1<=tp;++j)
                f[i][j]=Min(f[i-1][j],f[i-1][j+(1<<(i-1))]);
        while(m--){
            u=read(),v=read(),w=read(); p=lca(u,v);
            ins(rt[u],1,N-1,w,1);
            ins(rt[v],1,N-1,w,1);
            ins(rt[p],1,N-1,w,-1);
            if(fa[p]) ins(rt[fa[p]],1,N-1,w,-1);//拆成4个操作
        }
        for(ri i=n;i;--i)
            p=dfn[i],ans[p]=id[rt[p]],merge(rt[fa[p]],rt[p],1,N-1);
        for(ri i=1;i<=n;++i) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    查看linux服务器CPU相关
    Innobackupex(xtrabackup)物理备份
    给xen虚拟机添加硬盘分区格式化
    快速做ssh免密钥登陆
    windows基本命令大全
    linux系统下python升级安装
    快速安装Java环境
    「十二省联考 2019」骗分过样例
    「十二省联考 2019」皮配
    「SNOI2019」积木
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/11551849.html
Copyright © 2020-2023  润新知