zoukankan      html  css  js  c++  java
  • #4709. 树

    题目描述

    题解

    考虑一条路径 $(u,v)$ 的影响,那对 $lca$ 及其祖先的贡献都是 $(d_u-d_lca)(d_v-d_lca)$ ,对 $(u,v)$ 这条路径上的点,每个点和其子树内的贡献是一样的,列式子发现是等差数列的形式,于是我们可以做树上差分,具体来说我们发现对于 $(u,lca)$ 这条路径上的点 $x$ , $Delta a_x-Delta a_{son}=dis_{u,v}+1-2(dp_x-dp_u)$ ,于是我们可以在 $u$ 或 $v$ 上打上首项和公差的标记,在 $lca$ 上打上末项和公差的负标记,每次首项都加上公差即可

    效率: $O(nlogn)$ (需要倍增)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=3e5+5,M=N<<1;
    int n,m,hd[N],V[M],nx[M],t,dp[N],fa[N][20];
    long long a[N],b[N],s[N];
    void add(int u,int v){
        nx[++t]=hd[u];V[hd[u]=t]=v;
    }
    void dfs1(int u,int fr){
        dp[u]=dp[fa[u][0]=fr]+1;
        for (int i=1;fa[fa[u][i-1]][i-1];i++)
            fa[u][i]=fa[fa[u][i-1]][i-1];
        for (int i=hd[u];i;i=nx[i])
            if (V[i]!=fr) dfs1(V[i],u);
    }
    int lca(int u,int v){
        if (dp[u]<dp[v]) swap(u,v);
        for (int i=19;~i;i--)
            if (dp[fa[u][i]]>=dp[v]) u=fa[u][i];
        if (u==v) return u;
        for (int i=19;~i;i--)
            if (fa[u][i]!=fa[v][i])
                u=fa[u][i],v=fa[v][i];
        return fa[u][0];
    }
    void dfs2(int u,int fr){
        for (int v,i=hd[u];i;i=nx[i])
            if ((v=V[i])!=fr)
                dfs2(v,u),a[u]+=a[v],b[u]+=b[v];
        a[u]-=b[u];
    }
    void dfs3(int u,int fr){
        for (int v,i=hd[u];i;i=nx[i])
            if ((v=V[i])!=fr)
                s[v]=s[u]-a[v],dfs3(v,u);
    }
    int main(){
        cin>>n>>m;
        for (int i=1,u,v;i<n;i++)
            scanf("%d%d",&u,&v),
            add(u,v),add(v,u);
        dfs1(1,0);
        for (int u,v,z,l;m--;){
            scanf("%d%d",&u,&v);
            z=lca(u,v);l=dp[u]+dp[v]-(dp[z]<<1);
            a[u]+=l+1;a[v]+=l+1;a[z]-=2;
            b[u]+=2;b[v]+=2;b[z]-=4;
            s[1]+=1ll*(dp[u]-dp[z])*(dp[v]-dp[z]);
        }
        dfs2(1,0);dfs3(1,0);
        for (int i=1;i<=n;i++)
            printf("%lld
    ",s[i]);
        return 0;
    }
  • 相关阅读:
    如何将 Python 程序打包成 .exe 文件?
    无穷滚动(Infinite scroll)的实现原理
    图片延迟加载(lazyload)的实现原理
    Java 基础 -- 泛型、集合、IO、反射
    Ubuntu on win10
    让自己少走点弯路
    使用MongoDB 记录业务日志
    19个JavaScript数组常用方法总结
    Kubernetes 使用Nginx-Ingress实现蓝绿发布/金丝雀发布/AB测试
    官方golang包管理神器
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12283450.html
Copyright © 2011-2022 走看看