HDU - 4625 JZPTREE(第二类斯特林数+树DP)
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)的更多相关文章
- bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...
- 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 ...
- P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)
传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...
- BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)
传送门 解题思路 比较有意思的一道数学题.首先\(n*k^2\)的做法比较好想,就是维护一个\(x^i\)这种东西,然后转移的时候用二项式定理拆开转移.然后有一个比较有意思的结论就是把求\(x^i\) ...
- HDU4625 JZPTREE——第二类斯特林数
复杂度大概O(nk) 一些尝试:1.对每个点推出1,2,3,,,到k次方的值.但是临项递推二项式展开也要考虑到具体每个点的dist 2.相邻k次方递推呢?递推还是不能避免k次方的展开 k次方比较讨厌, ...
- hdu 2643 rank 第二类斯特林数
题意:给定n个人,要求这n个人的所有可能排名情况,可以多个人并列(这个是关键). 题解:由于存在并列的问题,那么对于n个人,我们最多有n个排名,枚举一下1~n,累加一下就好.(注意这里是变种的斯特林数 ...
- BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】
题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...
- BZOJ 2159: Crash 的文明世界 第二类斯特林数+树形dp
这个题非常巧妙啊~ #include <bits/stdc++.h> #define M 170 #define N 50003 #define mod 10007 #define LL ...
- 8-机器分配(hud4045-组合+第二类斯特林数)
http://acm.hdu.edu.cn/showproblem.php?pid=4045 Machine schedulingTime Limit: 5000/2000 MS (Java/Othe ...
随机推荐
- IDEA修改module的名字
首先右键module名,选择[Refactor]-[Rename...] 然后选择[Rename module] 只修改这些对于当前开发是没有问题了 但是刚开始把module添加成maven项目的时候 ...
- MT【296】必要性探路
已知$a,b\in R.f(x)=e^x-ax+b$,若$f(x)\ge1$恒成立,则$\dfrac{b-a}{a}$的取值范围_____ 提示:答案:$[-1,\infty)$取$x=0,b\ge0 ...
- MT【248】$f(x)=\dfrac{1}{x-1}+\dfrac{1}{x-b}$的性质
探讨函数$f(x)=\dfrac{1}{x-a}+\dfrac{1}{x-b}$其中$a<b$的几个性质 分析:对称性:关于$(\dfrac{a+b}{2},0)$证明提示:$f(x)+f(a+ ...
- 【Luogu2664】树上游戏(点分治)
[Luogu2664]树上游戏(点分治) 题面 洛谷 题解 很好的一道点分治题. 首先直接点分治,考虑过每个分治重心的链的贡献. 我们从分治重心开始找每种颜色,强制令一种颜色只在其到分治重心的链上第一 ...
- 【转】让浏览器格式化显示JSON数据之chrome jsonView插件安装
jsonView 用来让Chrome浏览器能格式化的显示JSON数据. 以上是网上找的方式,且试验成功! 步骤: 1.打开 https://github.com : 2.搜索 jsonView 链接: ...
- bzoj4240有趣的家庭菜园(贪心+逆序对)
对家庭菜园有兴趣的JOI君每年在自家的田地中种植一种叫做IOI草的植物.JOI君的田地沿东西方向被划分为N个区域,由西到东标号为1~N.IOI草一共有N株,每个区域种植着一株.在第i个区域种植的IOI ...
- Python数据结构之实现队列
再学习数据结构队列的时候,我不想讲太多!一切言语不如几张图来的实在! 这是第一张图,第二图是讲队列满的情况: 分析了数据结构中的队列是什么之后,我们开始写代码,代码Code如下: #coding:ut ...
- springcloud干货之服务注册与发现(Eureka)
springcloud系列文章的第一篇 springcloud服务注册与发现 使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介: Spring Cloud Eureka是Spr ...
- python描述器
描述器定义 python中,一个类实现了__get__,__set__,__delete__,三个方法中的任何一个方法就是描述器,仅实现__get__方法就是非数据描述器,同时实现__get__,__ ...
- JavaScript原型详解
1,前言 下面是2008年Github创建以来,各种编程语言的排名情况 排名其中JavaScript自2015年之后就盘踞第一名,成为github上被使用最多的语言,早期,JS的使用还主要集中于浏览器 ...