牛客练习赛55 E.树 树形dp

原题链接:https://ac.nowcoder.com/acm/contest/2927/E

题意

有一棵树,设 d i s ( x , y ) dis(x,y) dis(x,y)表示x到y的距离,求

∑ i = 1 n ∑ j = 1 n d i s 2 ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^{n}dis^2(i,j) i=1nj=1ndis2(i,j)

分析

树上路径有一种计算方法

d i s ( x , y ) = d e p [ x ] + d e p [ y ] − 2 ∗ d e p [ l c a ( x , y ) ] dis(x,y)=dep[x]+dep[y]-2*dep[lca(x,y)] dis(x,y)=dep[x]+dep[y]2dep[lca(x,y)]

那么

d i s 2 ( x , y ) = ( d e p [ x ] + d e p [ y ] − 2 ∗ d e p [ l c a ( x , y ) ] ) 2 dis^2(x,y)=(dep[x]+dep[y]-2*dep[lca(x,y)])^2 dis2(x,y)=(dep[x]+dep[y]2dep[lca(x,y)])2

= d e p [ x ] 2 + d e p [ y ] 2 + 2 ∗ d e p [ x ] d e p [ y ] − 4 ∗ d e p [ l c a ( x , y ) ] ( d e p [ x ] + d e p [ y ] ) + 4 ∗ d e p [ l c a ( x , y ) ] 2 =dep[x]^2+dep[y]^2+2*dep[x]dep[y]-4*dep[lca(x,y)](dep[x]+dep[y])+4*dep[lca(x,y)]^2 =dep[x]2+dep[y]2+2dep[x]dep[y]4dep[lca(x,y)](dep[x]+dep[y])+4dep[lca(x,y)]2

对于式子的前三项,可以在处理完所有深度之后O(n)计算得到,接着就是怎么算后面的部分

我们假设lca(x,y)=a,然后对于每一个a,我们对树进行遍历。对于a节点来说,假设b1,b2…bm是a节点的儿子节点,那么点对个数num可以轻松得到
n u m = s i z [ a ] ∗ s i z [ a ] − ∑ i = 1 s i z [ b i ] ∗ s i z [ b i ] num=siz[a]*siz[a]-\sum_{i=1}siz[b_{i}]*siz[b_{i}] num=siz[a]siz[a]i=1siz[bi]siz[bi]

易得 ∑ 4 ∗ d e p [ a ] 2 = 4 ∗ d e p [ a ] 2 ∗ n u m \sum4*dep[a]^2=4*dep[a]^2*num 4dep[a]2=4dep[a]2num

然后考虑 ∑ 4 ∗ d e p [ a ] ( d e p [ x ] + d e p [ y ] ) \sum 4*dep[a](dep[x]+dep[y]) 4dep[a](dep[x]+dep[y]),首先突破口就是所有点对的深度和,我们可以把深度和转化一下, d e p [ x ] + d e p [ y ] = 2 ∗ d e p [ a ] + d i s ( x , y ) dep[x]+dep[y]=2*dep[a]+dis(x,y) dep[x]+dep[y]=2dep[a]+dis(x,y),其中dis(x,y)就可以从每个子树开始出发,到除子树外所有点的距离和即 r e s = ∑ ( s i z [ a ] − b i ) ∗ s u m [ b i ] res = \sum (siz[a]-b_{i})*sum[b_{i}] res=(siz[a]bi)sum[bi],sum是所有子树节点到该节点的距离之和。

可以推出 ∑ 4 ∗ d e p [ a ] ( d e p [ x ] + d e p [ y ] ) = 4 ∗ r e s ∗ d e p [ a ] \sum 4*dep[a](dep[x]+dep[y])=4*res*dep[a] 4dep[a](dep[x]+dep[y])=4resdep[a]

Code

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define re register
typedef long long ll;
typedef pair<ll, ll> PII;
typedef unsigned long long ull;
const int N = 1e6 + 10, M = 1e6 + 5, INF = 0x3f3f3f3f;
const int MOD = 998244353;
vector<int> g[N];
ll siz[N], dep[N], sum[N], ans;
int n;
void dfs1(int x, int fa) {
    siz[x] = 1, dep[x] = dep[fa] + 1, sum[x] = dep[x];
    for (auto v : g[x]) {
        if (v == fa) continue;
        dfs1(v, x);
        siz[x] += siz[v];
        sum[x] += sum[v];
    }
}
void dfs2(int x, int fa) {
    ll num = siz[x] * siz[x] % MOD;
    ll res = 2 * dep[x] * siz[x] % MOD;
    for (auto v : g[x]) {
        if (v == fa) continue;
        dfs2(v, x);
        num = (num - siz[v] * siz[v] % MOD + MOD) % MOD;
        res = (res + 2 * sum[v] * (siz[x] - siz[v]) % MOD) % MOD;
    }
    ans = (ans + 4 * dep[x] % MOD * dep[x] % MOD * num % MOD - 4 * dep[x] % MOD * res % MOD + MOD) % MOD;
}
void solve() {
    cin >> n;
    for (int i = 1; i <= n-1; i ++) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs1(1, 0);
    dfs2(1, 0);
    ll tmp = 0;
    for (int i = 1; i <= n; i++) ans = (ans + 2 * dep[i] * dep[i] % MOD * n % MOD) % MOD, tmp = (tmp + dep[i]) % MOD;
    ans = (ans + 2 * tmp * tmp % MOD) % MOD;
    cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
#endif
    solve();
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip基于Django+python编写开发的毕业生就业管理系统支持学生教师角色+db数据库(毕业设计新项目).zip
毕设新项目基于python3.7+django+sqlite开发的学生就业管理系统源码+使用说明(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 学生就业管理系统(前端) ## 项目开发环境 - IDE: vscode - node版本: v12.14.1 - npm版本: 6.13.4 - vue版本: @vue/cli 4.1.2 - 操作系统: UOS 20 ## 1.进入项目目录安装依赖 ``` npm install ``` ## 2.命令行执行进入UI界面进行项目管理 ``` vue ui ``` ## 3.编译发布包(请注意编译后存储路径) #### PS:需要将编译后的包复制到后端项目的根目录下并命名为'static' 学生就业管理系统(后端) ## 1.项目开发环境 - IDE: vscode - Django版本: 3.0.3 - Python版本: python3.7.3 - 数据库 : sqlite3(测试专用) - 操作系统 : UOS 20 ## 2.csdn下载本项目并生成/安装依赖 ``` pip freeze > requirements.txt pip install -r requirements.txt ``` ## 3.项目MySQL数据库链接错误 [点击查看解决方法](https://www.cnblogs.com/izbw/p/11279237.html)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值