解题:国家集训队 Crash 的文明世界
这种套着高次幂的统计问题一般都要用到第二类斯特林数和自然数幂的关系:$a^k=\sum\limits_{i=0}^{k}S_k^iC_a^i*i!$
那么对于每个点$x$有:
$ans_x=\sum\limits_{i=0}^k S_{k}^i C_{\sum dis(x,j)}^i i!$
问题变成求$C_{\sum dis(x,j)}^i$,神仙告诉我们,这个东西要DP求
为什么要DP求?先往下看
那么就设$dp[i][k]$表示以i为根的子树里$C_{\sum dis(i,j)}^k$的值,$pd[i][k]$表示以$i$为根的子树外......的值
$dp$数组是符合我们常做的树形DP的思路的,先看这个
转移当然是从儿子合并啦:
$dp[i][k]=C_{\sum dis(i,j)}^k$
$=C_{\sum dis(son,j)+1}^k+[k==0]$
好,现在回答为什么要DP?因为根据组合数的性质$C_n^m=C_{n-1}^m+C_{n-1}^{m-1}$,这里可以直接转移
$=C_{\sum dis(son,j)}^k+C_{\sum dis(son,j)}^{k-1}+[k==0]$
$=dp[son][k]+dp[son][k-1]+[k==0]$
这样一来就可以从父亲往下转移求$pd$了,下面用$C'$表示从父亲转移过来时的组合数(区别于子树)
$dp[i][k]={C'}_{\sum dis(i,j)}^k$
$={C'}_{\sum dis(fth,j)+1}^k+C_{\sum dis(fth,j)+1}^k-C_{\sum dis(i,j)+1}^k$
爆拆一通得到:
$=pd[fth][k]+pd[fth][k-1]+dp[fth][k]+dp[fth][k-1]-dp[i][k]-2*dp[i][k-1]-dp[i][k-2]$
于是做完了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=,mod=;
int n,k,t1,t2,cnt;
int fac[N],inv[N],st2[M][M];
int p[N],noww[*N],goal[*N];
long long dp[N][M],pd[N][M];
void Add(long long &x,int y)
{
x+=y;
if(x>=mod) x-=mod;
}
int C(int n,int m)
{
return n<m?:1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int Qpow(int x,int k)
{
if(k==) return x;
int tmp=Qpow(x,k/);
return k%?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
}
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
noww[++cnt]=p[t];
goal[cnt]=f,p[t]=cnt;
}
void Pre()
{
fac[]=inv[]=,st2[][]=;
for(int i=;i<=k;i++)
for(int j=;j<=k;j++)
st2[i][j]=(st2[i-][j-]+1ll*st2[i-][j]*j%mod)%mod;
for(int i=;i<=k;i++)
fac[i]=1ll*fac[i-]*i%mod;
inv[k]=Qpow(fac[k],mod-);
for(int i=k-;i;i--)
inv[i]=1ll*inv[i+]*(i+)%mod;
}
void Gettre(int nde,int fth)
{
dp[nde][]=;
for(int i=p[nde],g;i;i=noww[i])
if(goal[i]!=fth)
{
Gettre(g=goal[i],nde);
Add(dp[nde][],dp[g][]);
for(int j=;j<=k;j++)
Add(dp[nde][j],(dp[g][j]+dp[g][j-])%mod);
}
}
void Getanc(int nde,int fth)
{
if(nde!=)
{
for(int i=;i<=k;i++)
{
pd[nde][i]=pd[fth][i]+dp[fth][i]-dp[nde][i];
if(i>=) pd[nde][i]+=pd[fth][i-]+dp[fth][i-]-*dp[nde][i-];
if(i>=) pd[nde][i]-=dp[nde][i-]; pd[nde][i]=(pd[nde][i]%mod+mod)%mod;
}
}
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth) Getanc(goal[i],nde);
}
int main()
{
scanf("%d%d",&n,&k),Pre();
for(int i=;i<n;i++)
scanf("%d%d",&t1,&t2),Link(t1,t2);
Gettre(,),Getanc(,);
for(int i=;i<=n;i++)
{
long long ans=;
for(int j=;j<=k;j++)
Add(ans,1ll*st2[k][j]*fac[j]%mod*(dp[i][j]+pd[i][j])%mod);
printf("%lld\n",ans);
}
return ;
}
解题:国家集训队 Crash 的文明世界的更多相关文章
- [国家集训队] Crash 的文明世界(第二类斯特林数)
题目 [国家集训队] Crash 的文明世界 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 \[\begin{aligned} ans_x&=\sum\limi ...
- [国家集训队] Crash的文明世界
Description 给定一棵 \(n\) 个点的树,对于每个点 \(i\) 求 \(S(i)=\sum\limits_{j=1}^n \operatorname{dist(i,j)}^k\) .\ ...
- [国家集训队] Crash 的文明世界
不错的树形$ DP$的题 可为什么我自带大常数啊$ cry$ 链接:here 题意:给定一棵$ n$个节点的树,边权为$ 1$,对于每个点$ x$求$ \sum\limits_{i=1}^n dist ...
- 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]
传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...
- P4827 [国家集训队] Crash 的文明世界
传送门:洛谷 题目大意:设$$S(i)=\sum_{j=1}^ndis(i,j)^k$$,求$S(1),S(2),\ldots,S(n)$. 数据范围:$n\leq 50000,k\leq 150$ ...
- 【[国家集训队] Crash 的文明世界】
先写一个五十分的思路吧 首先这道题有一个弱化版 [POI2008]STA-Station 相当于\(k=1\),于是就是一个非常简单的树形\(dp\)的\(up\ \ and\ \ down\)思想 ...
- P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)
传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...
- 洛谷 P4827 [国家集训队] Crash 的文明世界
题目描述 给你一棵 n 个点的树,对于树上的每个节点 i,求 \(\sum_{j=1}^ndis(i,j)^k\).其中 \(dis(i,j)\) 为两点在树上的距离. 输入格式 第一行两个整 ...
随机推荐
- 6.Xilinx RapidIO核仿真与包时序分析
转自https://www.cnblogs.com/liujinggang/p/10123498.html 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件 ...
- libgdx学习记录1——图片显示Texture
libgdx底层采用opengl渲染,对图片进行了优化处理,与android原生态的bitmap不太一样. 相比而言,效率要高一些,不过只支持png,jpg,bmp三种格式. 显示中,一般将图片放在a ...
- 您需要来自XXX的权限才能对此文件夹进行更改
解决办法: cmd命令:del/f/s/q 文件夹
- Linux Mint安装Docker踩坑指南
我家的服务器选用的Linux Mint系统,最近安装Docker的时候踩了一些小坑,但是总体还算顺利. 我们都知道Linux Mint系统是基于Ubuntu的,说实话用起来感觉还是很不错的,安装Doc ...
- 微信小程序选择并上传图片
上传图片 API: wx.chooseImage() 和 wx.uploadFile() wx.chooseImage({ count: 1, // 默认9 sizeType: ['origina ...
- Accer 4752G添加固态硬盘 双系统
(此文一直在草稿箱里躺了一年,略作修改后发布~) 背景:电脑是2011年年末买的,用到现在也已经5年多了,好在没坏过什么硬件,有过2年疯狂打LOL的经历,之后电脑就打不动了,FPS始终上不去,启动游戏 ...
- Bitcoin区块验证
目录 区块的生成 区块的验证链接 验证过程 Merkle Tree结构 区块的生成 矿工在挖矿前要组建区块 将coinbase交易打包进区块 将交易池中高优先级的交易打包进区块 优先级 = 交易的额度 ...
- python爬虫-使用cookie登录
前言: 什么是cookie? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想 ...
- 作业要求20160901 从edu.cnblogs.com中抄过来的,备忘
[已完成] 杨贵福 发布于 2016-09-01 21:51 开通技术博客,博客园 cnblogs 关注 杨贵福 younggift,回贴 "构建之法东北师大站,继续 2016秋" ...
- javascript 数组对象及其方法
数组声明:通过let arr = new Array(); 或者 let arr = []; 数组对象可调用的方法: 1)find方法,使用情况是对数组进行筛选遍历,find方法要求某个函数(A)作为 ...