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 ...
随机推荐
- 【UOJ349】【WC2018】即时战略 LCT 动态点分治
这是一道交互题 题目大意 有一棵\(n\)个点的树.最开始\(1\)号点是白的,其他点是黑的. 每次你可以执行一个操作:\(explore(x,y)\).要求\(x\)是一个白点.该函数会返回从\(x ...
- MT【289】含参绝对值的最大值之三
已知$a>0$,函数$f(x)=e^x+3ax^2-2e x-a+1$,(1)若$f(x)$在$[0,1]$上单调递减,求$a$的取值范围.(2)$|f(x)|\le1$对任意$x\in[0,1 ...
- 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...
- 【Gym 100971G】Repair
BUPT 2017 summer training (for 16) #1B 题意 Alex is repairing his country house. He has a rectangular ...
- 【map】p1184 高手之在一起
题目背景 高手是可以复活的,这点我们大家都知道. 题目描述 高手列出了一个详尽的日程表,这次他要追求的则是一个心灵纯洁的小萝莉.他和她都是要上课的,但是也会有时间空闲,于是高手决定无时无刻都要跟着她. ...
- bzoj3756pty的字符串(后缀自动机+计数)
题目描述 题解 我们可以先对trie树建出广义SAM,然后维护一下right集合大小(注意right集合在广义SAM上的维护方式). 然后把匹配穿往广义SAM上匹配,假设现在匹配到了x节点,那么x的所 ...
- VCC、VDD和VSS
在电子电路中,常可以看到VCC.VDD和VSS三种不同的符号,它们有什么区别呢? 一.解释 VCC:C=circuit 表示电路的意思, 即接入电路的电压: VDD:D=device 表示器件的意思 ...
- Centos 7下下载和安装docker
sudo yum install -y device-mapper sudo modprobe dm_mod ls -l /sys/class/misc/device-mapper sudo rpm ...
- Qt5应用改变窗口大小时出现黑影
解决方法 在启动程序时,添加-platform wayland参数 添加QT_QPA_PLATFORM=wayland-egl到系统环境变量 注意:改完后虽然没有黑影,但软件图标显示不正常,也不能正常 ...
- 洛谷P2824 排序
解:splay + 线段树合并,分裂. 首先有个乱搞做法是外层拿splay维护,有序区间缩成splay上一个节点.内层再开个数据结构支持合并分裂有序集合. 内层我一开始想的是splay,然后就没有复杂 ...