传送门

这个题......我谔谔

首先可以考虑换根\(dp\),但到后来发现二项式定理展开过后需要维护\(k\)个值,同时每个值也要\(O(k)\)的时间按二项式定理算 当然fft优化过后就是k log k了...

这样复杂度是\(O(nk^2)\)的

当然\(FFT\)优化过后就变成\(O(nk \log k)\)了

这复杂度感觉是对的?但FFT的大常数好像被卡成\(50\)了 跟没优化一样,没试过qwq

然后发现又可以点分治,复杂度\(O(nk \log n)\),跑的好像比\(O(nk \log k)\)的FFT换根dp快?然后也收获了\(50\)分的好成绩...这真是令人谔谔

好像还有FFT优化点分治的,就可以过了,然而窝不会...

这里应该有一个更妙的做法。

注意到\(x^n\),其组合意义就是把\(n\)个不同的求随便往\(x\)个不同的盒子里扔的方案数。

这样有些盒子是空的,枚举有求的盒子个数,可以得到

\[x^n = \sum\limits_{k=0}^x \begin{Bmatrix}n \\ k\end{Bmatrix} [x]_k
\]

其实上面那个\(k\)的范围到\(n\)也是可以的,因为大于\(x\)过后下降幂将会变成\(0\),下面为了好看就到\(n\)吧

其中\(\begin{Bmatrix}n\\k\end{Bmatrix}\)表示第二类斯特林数,\([x]_k = \prod\limits_{i=0}^{k-1}(x-i)\),注意因为\(n \ge 1\),所以\(\begin{Bmatrix}n\\0\end{Bmatrix}=0\),\(k\)从\(0\)开始也没事。

更进一步的将下降幂写成组合数的形式有

\[x^n = \sum\limits_{k=0}^n \begin{Bmatrix}n\\k\end{Bmatrix} \binom{x}{k} k!
\]

写到题目里的柿子去

\[S(x) = \sum\limits_{i=1}^n \operatorname{dist}(x,i)^k
\]

\[= \sum\limits_{i=1}^n \sum\limits_{j=0}^k \begin{Bmatrix}k\\j\end{Bmatrix}\binom{\operatorname{dist}(x,i)}{j}j!
\]

\[= \sum\limits_{j=0}^k \begin{Bmatrix}k\\j\end{Bmatrix}j!\sum\limits_{i=1}^n \binom{\operatorname{dist}(x,i)}{j}
\]

考虑怎么计算后面的\(\sum\),这个鉴于这棵树没有边权,以及组合数的递推性质,后面的东西可以换根\(dp\)。

具体的,先以\(1\)号点为根,令

\[dp[x][j] = \sum\limits_{v \in x} \binom{\operatorname{dist}(x,v)}{j}
\]

\(v \in x\)表示\(v\)在\(x\)的子树内,\(v \in son_x\)表示\(v\)是\(x\)的一个儿子

那么由于

\[\binom{\operatorname{dist}(x,v)}{j} = \binom{\operatorname{dist}(x,v)-1}{j}+\binom{\operatorname{dist}(x,v)-1}{j-1}
\]

有转移

\[dp[x][j] = \sum\limits_{v \in son_x} dp[v][j-1]+dp[v][j]
\]

特别的\(dp[x][0]=\sum\limits_{v \in son_x} dp[v][0]\)

那再令\(f[x][j]\)表示以\(x\)为根时的和,换根\(dp\)算出\(f[x][j]\)就好了,最后的答案

\[Ans_x = \sum\limits_{j=0}^k \begin{Bmatrix}k\\j\end{Bmatrix}j!f[x][j]
\]

预处理出斯特林数和阶乘就好了,复杂度\(O(nk + k^2)\)

\(Code:\)

#include <bits/stdc++.h>
using namespace std;
#define fore(i,x) for(int i=head[x],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
const int N=5e4+10,P=10007;
inline int add(int x,int y){return (x+=y)>=P?x-P:x;}
inline int sub(int x,int y){return (x-=y)<0?x+P:x;}
inline int fpow(int x,int y)
{
int ret=1; for(;y;y>>=1,x=1ll*x*x%P)
if(y&1) ret=1ll*ret*x%P;
return ret;
}
int n,K;
struct edge
{
int to,nxt;
}e[N<<1];
int head[N],cnt=0;
inline void ade(int x,int y)
{e[++cnt]=(edge){y,head[x]};head[x]=cnt;}
inline void addedge(int x,int y){ade(x,y),ade(y,x);}
int dp[N][233],f[N][233];
void dfs(int x,int prev)
{
dp[x][0]=1;
fore(_,x) if(v!=prev)
{
dfs(v,x);
dp[x][0]=add(dp[x][0],dp[v][0]);
for(int i=1;i<=K;i++)
dp[x][i]=add(dp[x][i],add(dp[v][i-1],dp[v][i]));
}
}
void getans(int x,int prev)
{
fore(_,x) if(v!=prev)
{
static int fx[233];
fx[0]=sub(f[x][0],dp[v][0]);
f[v][0]=add(dp[v][0],fx[0]);
for(int i=1;i<=K;i++) fx[i]=sub(f[x][i],add(dp[v][i-1],dp[v][i]));
for(int i=1;i<=K;i++)
f[v][i]=add(dp[v][i],add(fx[i-1],fx[i]));
getans(v,x);
}
}
int S[233][233],fac[233];
int main()
{
scanf("%d%d",&n,&K);
fac[0]=1;for(int i=1;i<=K;i++) fac[i]=fac[i-1]*i%P;
S[0][0]=1;
for(int i=1;i<=K;i++)
for(int j=1;j<=K;j++)
S[i][j]=add(S[i-1][j]*j%P,S[i-1][j-1]);
for(int i=1,x,y;i<n;i++)
scanf("%d%d",&x,&y),addedge(x,y);
dfs(1,0);
for(int i=0;i<=K;i++) f[1][i]=dp[1][i];
getans(1,0);
for(int i=1;i<=n;i++)
{
int ans=0;
for(int j=0;j<=K;j++)
ans=add(ans,S[K][j]*fac[j]%P*f[i][j]%P);
printf("%d\n",ans);
}
return 0;
}

[题解] LuoguP4827 [国家集训队] Crash 的文明世界的更多相关文章

  1. [国家集训队] Crash 的文明世界(第二类斯特林数)

    题目 [国家集训队] Crash 的文明世界 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 \[\begin{aligned} ans_x&=\sum\limi ...

  2. [国家集训队] Crash的文明世界

    Description 给定一棵 \(n\) 个点的树,对于每个点 \(i\) 求 \(S(i)=\sum\limits_{j=1}^n \operatorname{dist(i,j)}^k\) .\ ...

  3. [国家集训队] Crash 的文明世界

    不错的树形$ DP$的题 可为什么我自带大常数啊$ cry$ 链接:here 题意:给定一棵$ n$个节点的树,边权为$ 1$,对于每个点$ x$求$ \sum\limits_{i=1}^n dist ...

  4. 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]

    传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...

  5. P4827 [国家集训队] Crash 的文明世界

    传送门:洛谷 题目大意:设$$S(i)=\sum_{j=1}^ndis(i,j)^k$$,求$S(1),S(2),\ldots,S(n)$. 数据范围:$n\leq 50000,k\leq 150$ ...

  6. 解题:国家集训队 Crash 的文明世界

    题面 这种套着高次幂的统计问题一般都要用到第二类斯特林数和自然数幂的关系:$a^k=\sum\limits_{i=0}^{k}S_k^iC_a^i*i!$ 那么对于每个点$x$有: $ans_x=\s ...

  7. 【[国家集训队] Crash 的文明世界】

    先写一个五十分的思路吧 首先这道题有一个弱化版 [POI2008]STA-Station 相当于\(k=1\),于是就是一个非常简单的树形\(dp\)的\(up\ \ and\ \ down\)思想 ...

  8. P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)

    传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...

  9. 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4827 ​ 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...

随机推荐

  1. Acwing272 最长公共上升子序列

    题目大意:给定两个大小为n的数组,让你找出最长公共上升子序列的长度. 分析:这是一个比较好的dp题,LIS和LCS两大经典线性dp问题相结合,简称LCIS. 代码(O(n*n*n)写法): #incl ...

  2. Hadoop基准测试(二)

    Hadoop Examples 除了<Hadoop基准测试(一)>提到的测试,Hadoop还自带了一些例子,比如WordCount和TeraSort,这些例子在hadoop-example ...

  3. 【Linux】centos7下解决yum -y install mysql-server 没有可用包

    第一步:安装从网上下载文件的wget命令 [root@localhost ~]# yum -y install wget 第二步:下载mysql的repo源 [root@localhost ~]# w ...

  4. SQL批量插入表类 SqlBulkInsert

    ado.net已经有了sqlBulkCopy, 但是那个用xml格式,网络传输数据量太大. 自己实现了一个,传输尽量少的字节. 性能没对比过,有需要的自己拿去测试. using System.Data ...

  5. OSX10.10 Yosemite安装Metasploit

    安装环境 操作时间: 2015/6/8 操作系统: OSX Yosemite 10.10.3 Metasploit版本: v4.11.0-dev [core:4.11.0.pre.dev api:1. ...

  6. GNS3 icmp之严格路由

    路由配置: icmp记录路由抓取出接口的IP地址,最多可以抓取9个.ip协议头中的options为40个字节 R1 : conf t int f0/0 no shutdown ip add 192.1 ...

  7. 第1节 IMPALA:3、impala软件的下载和linux磁盘的挂载

    1. impala安装软件下载: http://archive.cloudera.com/cdh5/repo-as-tarball/5.14.0/ 2. linux磁盘的挂载: [root@node0 ...

  8. nodejs配置 https服务

    const port = normalizePort(process.env.PORT || '3000'); const path = require('path'); const https =  ...

  9. springmvc 后台实体类接受前端json字符串时,其中一个属性content 接受富文本内容时 标签<p>、<span> 这些标签丢失问题解决

    问题描述: 前端一个字段 <script id="editor" type="text/plain" name="content" s ...

  10. Linux-10Year

    主流Linux发行版近10年排行曲线 10个主流的发行版概述(distrowatch挑选) 搜索特定的发行 选择建议     初级用户选择:开箱即用     中级用户组装:适合你自己的系统     高 ...