Codeforces 题目传送门 & 洛谷题目传送门

首先看到这题我的第一反应是:这题跟这题长得好像,不管三七二十一先把 \(k\) 次方展开成斯特林数的形式,\(f(X)^k=\sum\limits_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}\dbinom{f(X)}{i}\),于是我们只需对所有 \(i\in[0,k]\) 求出 \(\sum\dbinom{f(X)}{i}\) 即可。

然后就不会做了/dk/wq

考虑 \(\dbinom{f(X)}{i}\) 的组合意义,相当于是从虚树的边中选择 \(i\) 条边染上颜色的方案数。故考虑 \(dp\),\(dp_{u,i}\) 表示对于 \(f(S)\subset subtree(u)\cup e(u,fa_u)\) 的点集 \(S\),从 \(f(S)\) 中选择 \(i\) 条边染上颜色的方案数,其中 \(e(u,v)\) 为 \(u,v\) 之间的边。

不难发现这东西转移实际上就是一个树上背包,\(dp_{u,i}=\sum\limits_{j=0}^idp_{v,j}dp_{u,i-j}\),初始值 \(dp_{u,0}=2\)(\(u\in S\) 或 \(u\notin S\))。最后,由于我们只考虑了 \(u\) 子树内的边的贡献,未考虑 \(u\to fa_u\) 的边的贡献,故需再令 \(dp_{u,i}=dp_{u,i}+dp_{u,i-1}\)(选择这条边或不选这条边)。

最后是计算答案,记 \(ans_i=\sum\dbinom{f(X)}{i}\),对于每个点 \(u\),考虑该点为虚树根时的贡献 ,就是 \(dp_{u,i}\) 减去只包含在一个子树内的情况,这个在计算 \(dp_{u,i}\) 的过程中算一下就行了。

根据背包均摊可知复杂度 \(\mathcal O(nk)\)。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1e5;
const int MAXK=200;
const int MOD=1e9+7;
int n,k,hd[MAXN+5],to[MAXN*2+5],nxt[MAXN*2+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
int dp[MAXN+5][MAXK+5],siz[MAXN+5],tmp[MAXK+5],ans[MAXN+5];
int s[MAXK+5][MAXK+5],fac[MAXK+5];
void prework(int k){
fac[0]=s[0][0]=1;for(int i=1;i<=k;i++) fac[i]=1ll*fac[i-1]*i%MOD;
for(int i=1;i<=k;i++) for(int j=1;j<=i;j++) s[i][j]=(s[i-1][j-1]+1ll*j*s[i-1][j])%MOD;
}
void dfs(int x,int f){
siz[x]=1;dp[x][0]=2;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];if(y==f) continue;
dfs(y,x);memset(tmp,0,sizeof(tmp));
for(int i=0;i<=min(siz[y],k);i++) for(int j=0;j<=min(k-i,siz[x]);j++)
tmp[i+j]=(tmp[i+j]+1ll*dp[y][i]*dp[x][j])%MOD;
siz[x]+=siz[y];for(int i=0;i<=min(siz[x],k);i++) dp[x][i]=tmp[i];
for(int i=0;i<=min(siz[y],k);i++) ans[i]=(ans[i]-dp[y][i]+MOD)%MOD;
}
for(int i=0;i<=min(siz[x],k);i++) ans[i]=(ans[i]+dp[x][i])%MOD;
for(int i=min(siz[x],k);i;i--) dp[x][i]=(dp[x][i]+dp[x][i-1])%MOD;
dp[x][1]--;if(dp[x][1]<0) dp[x][1]+=MOD;
}
int main(){
scanf("%d%d",&n,&k);prework(k);int sum=0;
for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),adde(u,v),adde(v,u);dfs(1,0);
for(int i=0;i<=k;i++) sum=(sum+1ll*fac[i]*s[k][i]%MOD*ans[i])%MOD;
printf("%d\n",sum);
return 0;
}

Codeforces 1097G - Vladislav and a Great Legend(第二类斯特林数+树上背包)的更多相关文章

  1. Codeforces Round #100 E. New Year Garland (第二类斯特林数+dp)

    题目链接: http://codeforces.com/problemset/problem/140/E 题意: 圣诞树上挂彩球,要求从上到下挂\(n\)层彩球.已知有\(m\)种颜色的球,球的数量不 ...

  2. Codeforces 1097G Vladislav and a Great Legend [树形DP,斯特林数]

    洛谷 Codeforces 这题真是妙的很. 通过看题解,终于知道了\(\sum_n f(n)^k​\)这种东西怎么算. update:经过思考,我对这题有了更深的理解,现将更新内容放在原题解下方. ...

  3. Codeforces 1528F - AmShZ Farm(转化+NTT+推式子+第二类斯特林数)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙题,只不过感觉有点强行二合一(?). 首先考虑什么样的数组 \(a\) 符合条件,我们考虑一个贪心的思想,我们从前到后遍历,对于每一个 ...

  4. Codeforces 932 E Team Work ( 第二类斯特林数、下降阶乘幂、组合数学 )

    题目链接 题意 : 其实就是要求 分析 : 先暴力将次方通过第二类斯特林数转化成下降幂 ( 套路?) 然后再一步步化简.使得最外层和 N 有关的 ∑ 划掉 这里有个技巧就是 将组合数的表达式放到一边. ...

  5. codeforces 1278F - Cards(第二类斯特林数+二项式)

    传送门 解题过程: \(答案=\sum^n_{i=0}*C^i_n*{\frac{1}{m}}^i*{\frac{m-1}{m}}^{n-i}*i^k\) 根据第二类斯特林数的性质\(n^k=\sum ...

  6. 【CF961G】Partitions(第二类斯特林数)

    [CF961G]Partitions(第二类斯特林数) 题面 CodeForces 洛谷 题解 考虑每个数的贡献,显然每个数前面贡献的系数都是一样的. 枚举当前数所在的集合大小,所以前面的系数\(p\ ...

  7. Gym Gym 101147G 第二类斯特林数

    题目链接:http://codeforces.com/gym/101147/problem/G 题意:n个人,去参加k个游戏,k个游戏必须非空,有多少种放法? 分析: 第二类斯特林数,划分好k个集合后 ...

  8. Gym - 101147G G - The Galactic Olympics —— 组合数学 - 第二类斯特林数

    题目链接:http://codeforces.com/gym/101147/problem/G G. The Galactic Olympics time limit per test 2.0 s m ...

  9. 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)

    [BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...

随机推荐

  1. 实现服务器和客户端数据交互,Java Socket有妙招

    摘要:在Java SDK中,对于Socket原生提供了支持,它分为ServerSocket和Socket. 本文分享自华为云社区<Java Socket 如何实现服务器和客户端数据交互>, ...

  2. Scrum Meeting 0529

    零.说明 日期:2021-5-29 任务:简要汇报七日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 七日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 完成后端管 ...

  3. Noip模拟69 2021.10.5

    考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...

  4. windows下wchar_t的问题

    使用vs新建工程或者编译工程的时候默认在编译设置里面讲wchar_t设置为内置类型,如下图: 但是在编译相互依赖的工程的时候,如果有的工程不将wchar_t设置为内置类型的时候,将会出现链接错误,需要 ...

  5. 小白学习C语言必背的18个经典程序

    1./*输出9*9口诀.共9行9列,i控制行,j控制列.*/ #include "stdio.h" main() {int i,j,result; for (i=1;i<10 ...

  6. 常用JAVA API :HashSet 和 TreeSet

    set容器的特点是不包含重复元素,也就是说自动去重. HashSet HashSet基于哈希表实现,无序. add(E e)//如果容器中不包含此元素,则添加. clear()//清空 contain ...

  7. 洛谷 P5785 [SDOI2012] 任务安排

    链接: P5785 弱化版:P2365 题意: 有 \(n\) 个任务待完成,每个任务有一个完成时间 \(t_i\) 和费用系数 \(f_i\),相邻的任务可以被分成一批.从零时刻开始这些任务会被机器 ...

  8. [转]DDR内存条rank的概念和区分

    1:什么是RANK? 答:CPU与内存之间的接口位宽是64bit,也就意味着CPU在一个时钟周期内会向内存发送或从内存读取64bit的数据.可是,单个内存颗粒的位宽仅有4bit.8bit或16bit, ...

  9. 一、安装zabbix监控(源码编方式)

    首先介绍一下zabbix的运行原理和运行条件. Zabbix监控原理 Zabbix 通过C/S 模式采集数据,通过B/S模式在web 端展示和配置.  被监控端:主机通过安装agent 方式采集数据, ...

  10. JMH 使用指南

    简介 JMH(Java Microbenchmark Harness)是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级.该工具是由 Oracle 内部实现 JIT 的大 ...