https://vjudge.net/problem/HDU-4625

题意

给出一颗树,边权为1,对于每个结点u,求sigma(dist(u,v)^k)。

分析

贴个官方题解

n^k并不好转移,于是用第二类斯特林数转化一下,这样可以预处理第二类斯特林数,而sigma(C(dist(u,v),i))则利用C(n,x)=C(n-1,x)+C(n-1,x-1)来进行树DP转移得到。

设dp[u][k]=sigma(C(dist(u,v),k)),则dp[u][k]=dp[v][k]+dp[v][k-1],这里v是u的儿子。先dfs一次算dp值。

接下来再dfs一次,每次以u为根,计算Eu,注意转移时需要将子结点作为新的根,此时需要计算一下合适的dp值。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1.0)
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = 5e4+;
const int maxm = 1e5+;
const int mod = ;
struct edge{
int t,n;
edge(int t=,int n=):
t(t),n(n){}
}e[maxn<<];
int head[maxn],tot;
void addedge(int u,int v){
e[++tot]=edge(v,head[u]),head[u]=tot;
e[++tot]=edge(u,head[v]),head[v]=tot;
}
int n,k;
int s[][],fac[];
void init(){
s[][]=fac[]=;
for(int i=;i<;i++){
fac[i]=fac[i-]*i%mod;
for(int j=;j<;j++){
s[i][j]=(j*s[i-][j]+s[i-][j-])%mod;
}
}
for(int i=;i<;i++)
for(int j=;j<;j++)
s[i][j]=s[i][j]*fac[j]%mod;
}
int dp[maxn][];
void pre_dfs(int u,int p){
dp[u][]=;
for(int i=;i<=k;i++) dp[u][i]=;
for(int i=head[u];~i;i=e[i].n){
int v = e[i].t;
if(v!=p){
pre_dfs(v,u);
for(int j=;j<=k;j++){
dp[u][j]+=dp[v][j];
if(j) dp[u][j]+=dp[v][j-];
dp[u][j]%=mod;
}
}
}
}
int ans[maxn];
void dfs(int u,int p){
ans[u]=;
for(int i=;i<=k;i++) ans[u]=(ans[u]+s[k][i]*dp[u][i])%mod;
for(int i=head[u];~i;i=e[i].n){
int v=e[i].t;
if(v!=p){
for(int j=;j<=k;j++){
dp[u][j]+=mod-dp[v][j];
if(j) dp[u][j]+=mod-dp[v][j-];
dp[u][j]%=mod;
}
for(int j=;j<=k;j++){
dp[v][j]+=dp[u][j];
if(j) dp[v][j]+=dp[u][j-];
dp[v][j]%=mod;
}
dfs(v,u);
for(int j=;j<=k;j++){
dp[v][j]+=mod-dp[u][j];
if(j) dp[v][j]+=mod-dp[u][j-];
dp[v][j]%=mod;
}
for(int j=;j<=k;j++){
dp[u][j]+=dp[v][j];
if(j) dp[u][j]+=dp[v][j-];
dp[u][j]%=mod;
}
}
}
}
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
scanf("%d",&t);
init();
while(t--){
tot=;
memset(head,-,sizeof head);
int u,v;
scanf("%d%d",&n,&k);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
}
pre_dfs(,-);
dfs(,-);
for(int i=;i<=n;i++) printf("%d\n",ans[i]);
}
return ;
}

HDU - 4625 JZPTREE(第二类斯特林数+树DP)的更多相关文章

  1. bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...

  2. bzoj 2159 Crash 的文明世界 & hdu 4625 JZPTREE —— 第二类斯特林数+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 使用公式:\( n^{k} = \sum\limits_{i=0}^{k} S(k,i ...

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

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

  4. BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)

    传送门 解题思路 比较有意思的一道数学题.首先\(n*k^2\)的做法比较好想,就是维护一个\(x^i\)这种东西,然后转移的时候用二项式定理拆开转移.然后有一个比较有意思的结论就是把求\(x^i\) ...

  5. HDU4625 JZPTREE——第二类斯特林数

    复杂度大概O(nk) 一些尝试:1.对每个点推出1,2,3,,,到k次方的值.但是临项递推二项式展开也要考虑到具体每个点的dist 2.相邻k次方递推呢?递推还是不能避免k次方的展开 k次方比较讨厌, ...

  6. hdu 2643 rank 第二类斯特林数

    题意:给定n个人,要求这n个人的所有可能排名情况,可以多个人并列(这个是关键). 题解:由于存在并列的问题,那么对于n个人,我们最多有n个排名,枚举一下1~n,累加一下就好.(注意这里是变种的斯特林数 ...

  7. BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】

    题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...

  8. BZOJ 2159: Crash 的文明世界 第二类斯特林数+树形dp

    这个题非常巧妙啊~ #include <bits/stdc++.h> #define M 170 #define N 50003 #define mod 10007 #define LL ...

  9. 8-机器分配(hud4045-组合+第二类斯特林数)

    http://acm.hdu.edu.cn/showproblem.php?pid=4045 Machine schedulingTime Limit: 5000/2000 MS (Java/Othe ...

随机推荐

  1. 自学Python3.6-算法 二分查找算法

    自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...

  2. 【BZOJ4911】[SDOI2017]切树游戏(动态dp,FWT)

    [BZOJ4911][SDOI2017]切树游戏(动态dp,FWT) 题面 BZOJ 洛谷 LOJ 题解 首先考虑如何暴力\(dp\),设\(f[i][S]\)表示当前以\(i\)节点为根节点,联通子 ...

  3. 录毛线脚本,直接抓包手写最简洁的LoadRunner性能测试脚本

    通常情况下,我们测试性能先要做单场景测试,即某个功能,一般情况下,这个功能依赖的功能(可能是需要先登录)不会太多, 如果录制脚本的话,会录制到很多无关的请求,大大增加了脚本的复杂度以及调整脚本的工作量 ...

  4. cobbler无人值守自动安装

      无人值守安装(自动按定制的需求来批量安装linux系统) kickstart cobbler linux安装系统的方法: 1,光盘 把iso镜像刻录(windows下有类似nero这类软件)到光盘 ...

  5. TensorFlow车牌识别实践(2)

    http://www.cnblogs.com/jackkwok/p/7228021.html 1,运行准备 按照https://github.com/matthewearl/deep-anpr说明的用 ...

  6. 在spring中如何生成一个bean (一个对象,比如jedis的连接池对象)【我】

    在spring中,要想生成一个单例对象(比如jedis的连接池对象) 方法1: 在 spring中用 bean 标签生成(反正就是让spring生成并管理单例的对象) 方法2: 把要生成的单例对象类, ...

  7. Mybatis非mapper代理配置

    转: Mybatis非mapper代理配置 2017年04月26日 20:13:48 待长的小蘑菇 阅读数:870   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...

  8. JAVA设计模式初探之适配器模式

    http://blog.csdn.net/jason0539/article/details/22468457 1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接 ...

  9. 解决jQuery ajax动态新增节点无法触发点击事件的问题

    在写ajax加载数据的时候发现,后面添加进来的demo节点元素,失去了之前的点击事件.为什么点击事件失效,我们该怎么去解决呢? 其实最简单的方法就是直接在标签中写onclick="" ...

  10. css3: 基本知识记录

    1.transition过渡: 元素从一种样式到另一种样式添加效果: div { transition: width 2s, height 2s, transform 2s; -moz-transit ...