题意:

给一棵N个点的树,对应于一个长为N的全排列,对于排列的每个相邻数字a和b,他们的贡献是对应树上顶点a和b的路径长,求所有排列的贡献和

思路:

对每一条边,边左边有x个点,右边有y个点,x+y=n,权值为w,则答案为$\displaystyle \sum 2xyw(n-1)!=\sum 2x(n-x)w(n-1)!$

其中每条边的x可以通过一次dfs找子树节点个数

比赛的时候找不到怎么又存权值又存子树节点个数的方法,瞎瘠薄调最后卡着空间时间过的,后来看别人代码学到了新方法:

比赛代码:

842MS 14012K
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e5+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);
vector<int>v[maxn];
ll w[maxn];
int f[maxn];
ll ans = ;
ll cnt[maxn];
ll dfs(int x, int fa){
ll tmp = ;
int sz = v[x].size();
if(sz==&&fa!=-)return f[x]=;
for(int i = ; i < sz; i++){
if(v[x][i]!=fa)tmp += dfs(v[x][i], x);
}
return f[x]=tmp;
}
void init(){
cnt[] = ;
for(int i = ; i < +; i++){
cnt[i] = cnt[i-]*i;
cnt[i]%=mod;
}
return;
}
inline int read(){
int num;
char ch;
while((ch=getchar())<'' || ch>'');
num=ch-'';
while((ch=getchar())>='' && ch<=''){
num=num*+ch-'';
}
return num;
}
struct Edge{
int u;
int v;
int w;
}edge[maxn];
int top = ;
void addedge(int u, int v, int w){
edge[top].u = u;
edge[top].v = v;
edge[top++].w = w;
} int main() {
int n;
init();
while(scanf("%d", &n)!=EOF){
top = ;
ans = ;
mem(f, );
for(int i = ; i <= n; i++){
v[i].clear();
}
for(int i = ; i <= n-; i++){
int x, y;
x=read();
y=read();
v[x].pb(y);
v[y].pb(x);
int c;
c = read();
addedge(x, y, c);
//mp[x][y] = mp[y][x] = c;
}
//ddfs(1, -1); dfs(, -);
f[] = ;
for(int i = ; i <= n-; i++){
int x = edge[i].u;
int y = edge[i].v;
int ww = edge[i].w;
//printf("%d %d %d %d\n", x, f[x], y, f[y]);
if(x==){
w[y] = ww;
continue;
}
else if(y==){
w[x] = ww;
continue;
}
if(f[x] < f[y]){
w[x] = ww;
continue;
}
else{
w[y] = ww;
continue;
}
} // for(int i = 1; i <= n; i++){
// printf("%d %d\n", i, w[i]);
// }
for(int i = ; i <= n; i++){
ll tmp = ;
tmp = *f[i];
tmp%=mod;
tmp *= (n-f[i]);
tmp%=mod;
tmp *= cnt[n-];
tmp %= mod;
tmp *= (ll)w[i];
ans += tmp;
ans %= mod;
}
printf("%I64d\n", ans);
} return ;
}

赛后代码:

499MS 18972K
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e5+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); ll d[maxn];
struct Edge{
int u;
ll w;
};
vector<Edge>v[maxn];
ll w[maxn];
int f[maxn];
int dfs(int x, int fa){
int sz = v[x].size();
int ans = ;
for(int i = ; i < sz; i++){
if(v[x][i].u==fa)w[x]=v[x][i].w;
else ans+=dfs(v[x][i].u, x);
}
if(sz==&&fa!=-)return f[x] = ;
return f[x] = ans;
}
int main() {
int n;
d[] = ;
for(int i = ; i < + ; i++){
d[i] = d[i-] *i;
d[i] %= mod;
}
while(~scanf("%d", &n)){
for(int i = ; i <= n; i++)v[i].clear();
//mem(f, 0);
for(int i = ; i < n-; i++){
int x, y;
ll l;
scanf("%d %d %I64d", &x, &y, &l);
Edge t1, t2;
t1.u=y;t2.u=x;
t1.w=t2.w=l;
v[x].pb(t1);
v[y].pb(t2);
}
ll ans = ;
dfs(, -);
for(int i = ; i <= n; i++){
ll tmp = d[n-];
tmp %= mod;
tmp *= (ll)*f[i]*(n-f[i]);
tmp %= mod;
tmp *= w[i];
tmp %= mod;
ans += tmp;
ans %= mod;
}
printf("%I64d\n", ans);
}
return ;
}

HDU6446 Tree and Permutation(树、推公式)的更多相关文章

  1. hdu6446 Tree and Permutation 2018ccpc网络赛 思维+dfs

    题目传送门 题目描述:给出一颗树,每条边都有权值,然后列出一个n的全排列,对于所有的全排列,比如1 2 3 4这样一个排列,要算出1到2的树上距离加2到3的树上距离加3到4的树上距离,这个和就是一个排 ...

  2. HDU6446 Tree and Permutation(树上DP)

    传送门:点我 Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (J ...

  3. 2020牛客寒假算法基础集训营2 J.求函数 (线段树 推公式 单点修改 区间查询)

    https://ac.nowcoder.com/acm/contest/3003/J 题解: #include<bits/stdc++.h> typedef long long ll; u ...

  4. hdu6446 Tree and Permutation

    没啥好说的,拆一下贡献就完事了.记dis(x,y)为树上x到y的最短路径,设长度为n的排列中有f(n)个里面x和y相邻(不考虑x和y的顺序),那么f(n)=(n-2)! (n-1) 2,显然这个f(n ...

  5. 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】

    Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  6. Tree and Permutation

    Tree and Permutation 给出一个1,2,3...N的排列,显然全部共有N!种排列,每种排列的数字代表树上的一个结点,设Pi是其中第i种排列的相邻数字表示的结点的距离之和,让我们求su ...

  7. Tree and Permutation (HDU 6446) 题解

    // 昨天打了一场网络赛,表现特别不好,当然题目难度确实影响了发挥,但还是说明自己太菜了,以后还要多多刷题. 2018 CCPC 网络赛 I - Tree and Permutation 简单说明一下 ...

  8. HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)

    在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平 ...

  9. HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu

    其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...

随机推荐

  1. owa部署

    新建一台win server 2012(注意如果是2008要补丁) 配置静态ip DNS指向ad域的ip 测试: ping 下ad域的域名,是通的继续 把本机加入到ad域 重启下 用admin登陆: ...

  2. 配置ca服务器和http,mail加密

    一·CA介绍 certificate authority   数字证书授权中心 被通信双方信任的.独立的第三方机构 负责证书颁发.验证.撤销等管理 数字证书 经证书授权中心数字签名的包含公开密钥拥有者 ...

  3. 快速部署postfix邮件服务器

    • 装包.配置.起服务– 默认的标准配置即可为本机提供发/收邮件服务– 若有必要,可扩大服务范围(邮件域) 前提:邮件服务器,必须为手工配置永久主机名虚拟机server0[root@server0 ~ ...

  4. Fabric1.4:链码管理与测试

    1 链码介绍 智能合约在 Hyperledger Fabric 中称为链码(chaincode),是提供分布式账本的状态处理逻辑.链码被部署在fabric 的网络节点中,能够独立运行在具有安全特性的受 ...

  5. Spring AOP 基于AspectJ

    简介 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持.因为Spring1.0的时候Aspectj还未出现; AspectJ1.5中新增了对 ...

  6. ArcGIS Desktop直连PostgreSQL安装及配置图解(windows)

    目录 1 PostgreSQL 11.0安装及配置 2 psqlODBC安装及配置 3 PostGIS安装及配置 4 pgAdmin4使用入门 5 空间数据导入 5.1 将PostgreSQL的bin ...

  7. Spring中常见的设计模式——适配器模式

    一.适配器模式的应用场景 适配器模式(Adapter Pattern)是指将一个类的接口转换成用户期待的另一个接口,使原本接口不兼容的类可以一起工作,属于构造设计模式. 适配器适用于以下几种业务场景: ...

  8. OpenGL ES for Android

    经过半年的准备OpenGL ES for Android系列文章终于要和大家见面了,在这里定一个小目标-先吸引1000个粉丝,万一实现了呢.写关于OpenGL ES的文章开始是有一些犹豫的,因为Ope ...

  9. springcloud初次zuul超时报错com.netflix.zuul.exception.ZuulException:Forwarding error

    报错如下 com.netflix.zuul.exception.ZuulException:Forwarding error Caused by: com.netflix.hystrix.except ...

  10. 关于C#程序的单元测试

    目录 1.单元测试概念 2.单元测试的原则 3.单元测试简单示例 4.单元测试框架特性标签 5.单元测试中的断言Assert 6.单元测试中验证预期的异常 7.单元测试中针对状态的间接测试 8.单元测 ...