题意:

给一棵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. IDEA错误: 找不到或无法加载主类

    错误: 找不到或无法加载主类 idea本身缓存问题 解决:清理缓存重启IDEA file-->invalidate Cache/restart 之后再重新build.

  2. BFT-SMaRt:用Java做节点间的可靠信道

    目录 一.引子 二.名词统一 1. 节点id 2. 节点 3. 本地节点 4. 配置域 5. TTP 6. 陌生域 三.节点服务类 四.节点通信系统概览 五.节点通信层准备 1. 创建socket服务 ...

  3. Scala实践13

    1.隐式参数 方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记.如果该参数列表中的参数没有像往常一样传递,Scala将查看它是否可以获得正确类型的隐式值,如果可以,则自动传递. S ...

  4. 头条面试竟然问我maven

    maven package和maven install 有什么区别? 你常用的maven命令有哪些? <dependencyManagement> 是干什么的? 还有用过其它构建工具吗? ...

  5. 跟着知识追寻者学BeautifulSoup,你学不会打不还口,骂不还手

    一 前言 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库:其强大的提取能力让知识追寻者放弃了使用正则匹配查找HTML节点:Beautifu Soup 其能直接 ...

  6. dp - 递推

    C. Multiplicity time limit per test 3 seconds memory limit per test 256 megabytes input standard inp ...

  7. 今天我的jupyter notebook打不开了,报错原因'No module named 'zmq.eventloop'

    今天我的jupyter notebook打不开了,就是那种一打开出现黑色界面就退出的那种,惊恐爬上了我的面颊. 找了一个小时,试了好几种办法(包括别人说的什么把属性里面后面的%%的去掉)终究无果 打开 ...

  8. matplotlib 条形图

    一.特点 离散数据,数据之间没有直接的关系 二.分类 1.垂直条形图 bar(x, height, width=0.8) # x 为x轴 # height 为y轴 # width 为 条形图的宽度 例 ...

  9. [洛谷P4707] 重返现世

    Description 为了打开返回现世的大门,\(Yopilla\) 需要制作开启大门的钥匙.\(Yopilla\) 所在的迷失大陆有 \(n\) 种原料,只需要集齐任意 \(k\) 种,就可以开始 ...

  10. NOI3.1 6377:生日相同 2.0

    描述 在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的名字,出生月日.试找出所有生日相同的学生. 输入 第一行为整数n,表示有n个学生,n ≤ 180.此后每行包含一个字符 ...