Codeforces 1097G - Vladislav and a Great Legend(第二类斯特林数+树上背包)
首先看到这题我的第一反应是:这题跟这题长得好像,不管三七二十一先把 \(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(第二类斯特林数+树上背包)的更多相关文章
- Codeforces Round #100 E. New Year Garland (第二类斯特林数+dp)
题目链接: http://codeforces.com/problemset/problem/140/E 题意: 圣诞树上挂彩球,要求从上到下挂\(n\)层彩球.已知有\(m\)种颜色的球,球的数量不 ...
- Codeforces 1097G Vladislav and a Great Legend [树形DP,斯特林数]
洛谷 Codeforces 这题真是妙的很. 通过看题解,终于知道了\(\sum_n f(n)^k\)这种东西怎么算. update:经过思考,我对这题有了更深的理解,现将更新内容放在原题解下方. ...
- Codeforces 1528F - AmShZ Farm(转化+NTT+推式子+第二类斯特林数)
Codeforces 题目传送门 & 洛谷题目传送门 神仙题,只不过感觉有点强行二合一(?). 首先考虑什么样的数组 \(a\) 符合条件,我们考虑一个贪心的思想,我们从前到后遍历,对于每一个 ...
- Codeforces 932 E Team Work ( 第二类斯特林数、下降阶乘幂、组合数学 )
题目链接 题意 : 其实就是要求 分析 : 先暴力将次方通过第二类斯特林数转化成下降幂 ( 套路?) 然后再一步步化简.使得最外层和 N 有关的 ∑ 划掉 这里有个技巧就是 将组合数的表达式放到一边. ...
- 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 ...
- 【CF961G】Partitions(第二类斯特林数)
[CF961G]Partitions(第二类斯特林数) 题面 CodeForces 洛谷 题解 考虑每个数的贡献,显然每个数前面贡献的系数都是一样的. 枚举当前数所在的集合大小,所以前面的系数\(p\ ...
- Gym Gym 101147G 第二类斯特林数
题目链接:http://codeforces.com/gym/101147/problem/G 题意:n个人,去参加k个游戏,k个游戏必须非空,有多少种放法? 分析: 第二类斯特林数,划分好k个集合后 ...
- 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 ...
- 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)
[BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...
随机推荐
- 剑指offer:JZ12 矩阵中的路径
JZ12 矩阵中的路径 描述 请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上, ...
- 什么是Sprint计划?
Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...
- zlib开发笔记(四):zlib库介绍、编译windows vs2015x64版本和工程模板
前言 Qt使用一些压缩解压功能,介绍过libzip库编译,本篇说明zlib库.需要用到zlib的msvc2015x64版本,编译一下. 版本编译引导 zlib在windows上的mingw32 ...
- 6月2日 Scrum Meeting
日期:2021年6月2日 会议主要内容概述: 取消账单类别自定义 图表属性分析取消函数输入 增加新的主题模板 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇 ...
- Unity 3D手游对不同分辨率屏幕的UI自适应
目前安卓手机的屏幕大小各异,没有统一的标准,因此用Unity 3D制作的手游需要做好对不同分辨率屏幕的UI自适应,否则就会出现UI大小不一和位置错位等问题. 我们的项目在开发时的参照分辨率(Refer ...
- 编写POC时候的几个参考项目
0x01. 背景 在编写pocsuite时候,会查阅大量的文件,poc利用方式. 1. pocsuite是什么 Pocsuite 是由知道创宇404实验室打造的一款开源的远程漏洞测试框架.它是知道 ...
- dhcpd:bad subnet number/mask combination. subnet
今天在调试wifi热点启动hdcpd服务时出现报错"bad subnet number/mask combination. subnet 192.168.1.1", Interne ...
- binary-tree-preorder-traversal leetcode C++
Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary t ...
- Zabbix5.0实现监控系统登陆失败告警
环境zabbix5.0,配置思路,通过添加监控项和触发器实现,监控项监控对应的日志文件,触发器过滤日志文件中的关键字,当出现failed时就发出告警. 监控项配置 类型选择zabbix客户端主动式,键 ...
- Arthas在线java进程诊断工具 在线调试神器
tag: java 诊断 堆栈 在线调试 耗时 死锁 arthas 阿里巴巴 Arthas (阿尔萨斯) Arthas 是 Alibaba 开源的Java诊断工具,深受开发者喜爱. 官网文档:http ...