zoukankan      html  css  js  c++  java
  • Luogu P4556 [Vani有约会]雨天的尾巴

    Link
    树上差分+线段树合并。

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<algorithm>
    const int N=100007,M=N*40,lim=100000;
    int cnt,fa[N],dep[N],size[N],son[N],top[N],ans[N],ch[M][2];
    struct pi{int fi,se;}t[M];
    std::vector<int>e[N];std::vector<pi>vec[N];
    int operator<(const pi&a,const pi&b){return a.se<b.se||(a.se==b.se&&a.fi>b.fi);}
    pi operator+(const pi&a,const pi&b){return {a.fi,a.se+b.se};}
    int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    int lca(int u,int v){for(;top[u]^top[v];u=fa[top[u]])if(dep[top[u]]<dep[top[v]])std::swap(u,v);return dep[u]<dep[v]? u:v;}
    #define mid ((l+r)>>1)
    void update(int p,int l,int r,pi x)
    {
        if(l+1==r) return t[p]=x+t[p],void();
        x.fi<=mid? update(ch[p][0]? ch[p][0]:ch[p][0]=++cnt,l,mid,x):update(ch[p][1]? ch[p][1]:ch[p][1]=++cnt,mid,r,x);
        t[p]=std::max(t[ch[p][0]],t[ch[p][1]]);
    }
    void merge(int u,int v,int l,int r)
    {
        if(l+1==r) return t[u]=t[u]+t[v],void();
        if(ch[u][0]&&ch[v][0]) merge(ch[u][0],ch[v][0],l,mid); else if(ch[v][0]) ch[u][0]=ch[v][0];
        if(ch[u][1]&&ch[v][1]) merge(ch[u][1],ch[v][1],mid,r); else if(ch[v][1]) ch[u][1]=ch[v][1];
        t[u]=std::max(t[ch[u][0]],t[ch[u][1]]);
    }
    #undef mid
    void dfs1(int u,int f)
    {
        dep[u]=dep[fa[u]=f]+1,size[u]=1;
        for(int v:e[u]) if(v^f) if(dfs1(v,u),size[u]+=size[v],size[v]>size[son[u]]) son[u]=v;
    }
    void dfs2(int u,int t)
    {
        top[u]=t;
        if(son[u]) dfs2(son[u],t);
        for(int v:e[u]) if(v^son[u]&&v^fa[u]) dfs2(v,v);
    }
    void dfs3(int u)
    {
        for(int v:e[u]) if(v^fa[u]) dfs3(v),merge(u,v,0,lim);
        auto it=vec[u].begin();
        for(auto it:vec[u])
    	update(u,0,lim,it);
        ans[u]=t[u].fi;
    }
    int main()
    {
        int n=read(),m=read();cnt=n;
        for(int i=1,u,v;i<n;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
        dfs1(1,0),dfs2(1,1);
        for(int i=1,u,v,w,p;i<=m;++i) u=read(),v=read(),w=read(),p=lca(u,v),vec[u].push_back({w,1}),vec[v].push_back({w,1}),vec[p].push_back({w,-1}),vec[fa[p]].push_back({w,-1});
        dfs3(1);
        for(int i=1;i<=n;++i) printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    深入浅出 Redis client/server 交互流程
    VMware三种网络连接模式(转载)
    ARP 原理及攻击
    symbol lookup error:undefined symbol
    printf 颜色格式串"33[34;1m"
    运行openvas
    openvas 安装
    升级openssl 支持TLS1.2
    Windows登录密码明文获取器
    Linux字符串截取和处理命令 cut、printf、awk、sed、sort、wc
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12487166.html
Copyright © 2011-2022 走看看