@description@

有n个城市,每个城市有个权值wi,任意两个城市i,j之间的道路数有wi∗wj条。

对于每种生成树,设每个点的度数为di,其权值定义为∏di。

问所有无根生成树的权值和。答案对1e9+7取模。

Class:

ConnectedStates

Method:

getSum

Parameters:

int[]

Returns:

int

Constraints

n <= 2000

Examples

0)

{"3, 10"}

Returns: 30

1)

{"2, 2, 2"}

Returns: 96

2)

{"1, 1, 1, 1"}

Returns: 60

@solution@

考虑如果固定了生成树的形态,对应的方案应该是所有树边条数的乘积。

稍微变一变其实就是 \(\prod_{i=1}^{n}w_{i}^{d_i}\),这样就只跟点的度数有关了。

根据我们的 prufer 定理,最终答案为:

\[ans = (n-2)!*\sum_{(\sum_{i=1}^{n}d_i) = 2*n-2}(\prod_{i=1}^{n}\frac{w_{i}^{d_i}}{(d_i-1)!}*d_i)
\]

如果将 i 有关的项整理到一起然后 fft 一下的时间复杂度是 O(n^2*logn),但是我们可以做到更优。

优化的思路来源在于多项式的幂公式,即:

\[(a_1 + a_2 + ... + a_n)^k = k!*\sum_{(\sum_{i=1}^{n}b_i) = k}(\prod_{i=1}^{n}\frac{a_{i}^{b_i}}{{b_i}!})
\]

注意到下面这个公式和上面的答案表达式其实是很相像的,我们考虑进一步地变形:

令 \(a_i = d_i - 1\),得到:

\[ans = (\prod_{i=1}^{n}w_i)*(n-2)!*\sum_{(\sum_{i=1}^{n}a_i) = n-2}(\prod_{i=1}^{n}\frac{w_{i}^{a_i}}{a_i!}*(a_i+1))
\]

基本就是一样了,但还有一个 \(\prod_{i=1}^{n}(a_i + 1)\) 阻碍我们。

考虑将它拆开,依次考虑每一个单项式 \(a_{p_1}*a_{p_2}*...*a_{p_m} = \prod_{j=1}^{m}a_{p_j}\) 的贡献,其中 \(1 \le p_1 < p_2 < ... < p_m \le n\)。它的贡献为:

\[\sum_{(\sum_{i=1}^{n}a_i) = n-2}(\prod_{i=1}^{n}\frac{w_{i}^{a_i}}{a_i!}* \prod_{j=1}^{m}a_{p_j})
\]

考虑将这些 a 乘入阶乘中去,令得到的新的阶乘分别为 \(c_1, c_2, ... c_n\),再变一下形得到:

\[\prod_{j=1}^{m}w_{p_j}*\sum_{(\sum_{i=1}^{n}c_i) = n-2-m}(\prod_{i=1}^{n}\frac{w_{i}^{c_i}}{c_i!}) = \prod_{j=1}^{m}w_{p_j}*\frac{(\sum_{i=1}^{n}w_i)^{n-2-m}}{(n-2-m)!}
\]

终于化成了我们想要的东西。

再将上面那个套入我们的答案表达式中,即可得到:

\[ans = \sum_{m=0}^{n-2}(\sum_{1 \le p_1 < p_2 < ... < p_m \le n}\prod_{j=1}^{m}w_{p_j})*\frac{(\sum_{i=1}^{n}w_i)^{n-2-m}}{(n-2-m)!}
\]

中间那个看似很鬼畜的式子用 dp 处理一下就好啦。时间复杂度 O(n^2)。

@accepted code@

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 2000;
const int MOD = int(1E9) + 7;
class ConnectedStates{
public:
int pow_mod(int b, int p) {
int ret = 1;
while( p ) {
if( p & 1 ) ret = 1LL*ret*b%MOD;
b = 1LL*b*b%MOD;
p >>= 1;
}
return ret;
}
int dp[MAXN + 5], w[MAXN + 5], pro, n;
int fct[MAXN + 5], ifct[MAXN + 5], pw[MAXN + 5];
void get_ready() {
dp[0] = 1;
for(int i=1;i<=n;i++)
for(int j=n;j>=1;j--)
dp[j] = (dp[j] + 1LL*dp[j-1]*w[i]%MOD)%MOD;
pw[0] = 1, pw[1] = 0, pro = 1;
for(int i=1;i<=n;i++)
pw[1] = (pw[1] + w[i])%MOD, pro = 1LL*pro*w[i]%MOD;
for(int i=2;i<=n;i++)
pw[i] = 1LL*pw[i-1]*pw[1]%MOD;
fct[0] = 1;
for(int i=1;i<=n;i++)
fct[i] = 1LL*fct[i-1]*i%MOD;
ifct[n] = pow_mod(fct[n], MOD - 2);
for(int i=n-1;i>=0;i--)
ifct[i] = 1LL*ifct[i+1]*(i+1)%MOD;
}
int getSum(vector<int>vec) {
n = vec.size();
for(int i=1;i<=n;i++)
w[i] = vec[i-1];
get_ready();
int ret = 0;
for(int i=0;i<=n-2;i++)
ret = (ret + 1LL*dp[i]*pw[n-2-i]%MOD*ifct[n-2-i]%MOD)%MOD;
return 1LL*ret*fct[n-2]%MOD*pro%MOD;
}
};

@details@

当我看到这个做法的瞬间:woc 这是什么神仙操作。

果真人类智慧啊。

但我觉得这个数据范围好像fft可以过?

@topcoder - SRM697D1L3@ ConnectedStates的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  8. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

  9. Topcoder Arena插件配置和训练指南

    一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...

随机推荐

  1. Java问题解读系列之String相关---String类为什么是final的?

    今天看到一篇名为<Java开发岗位面试题归类汇总>的博客,戳进去看了一下题目,觉得有必要夯实一下基本功了,所以打算边学边以博客的形式归纳总结,每天一道题, 并将该计划称为java问题解读系 ...

  2. linux系统服务

    系统服务分类,根据其使用的方法来分,可以被分为三类 a.由init控制的服务:基本都是系统级别的服务,运行级别这一章讲的就是这一类的服务 b.由System V启动脚本启动的服务:和我们打交道最多的一 ...

  3. python的pip更改源,因为我们处于局域网中

    很多时候,比如网络不给力,连接超时.防火墙阻挡等等各种原因,我们可能无法从Python官方的PyPi仓库进行pip安装,这时候可以选择国内的第三方源,推荐使用豆瓣源,速度不错. 使用方法: pip i ...

  4. ML面试1000题系列(81-90)

    本文总结ML面试常见的问题集 转载来源:https://blog.csdn.net/v_july_v/article/details/78121924 81.已知一组数据的协方差矩阵P,下面关于主分量 ...

  5. git 报错:没有权限 remote: error: unable to unlink old 'README.md' (Permission denied)

    解决:

  6. SpringCloud 融入 Python - Tornado

    前言 该篇文章分享如何将Python Web服务融入到Spring Cloud微服务体系中,并调用其服务,Python Web框架用的是Tornado 构建Python web服务 引入py-eure ...

  7. arcgis地图窗口操作

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. ATM系统和购物车系统 不需要文件支撑

    目录 ATM系统 购物车系统 ATM系统 #coding=utf8 #Version:python 3.6.4 #Tools:Python 2019.9.7 _data_ = '2019/9/7/01 ...

  9. 2017年浙工大迎新赛热身赛 J Forever97与寄信 【数论/素数/Codeforces Round #382 (Div. 2) D. Taxes】

    时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 131072K,其他语言262144K64bit IO Format: %lld 题目描述 Forever97与未央是一对笔友,他们经常互 ...

  10. TyvjP2018 「Nescafé26」小猫爬山

    P2018 「Nescafé26」小猫爬山 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Freda和rainbow饲养了N只小猫,这天,小猫们要去爬山.经 ...