UOJ#449. 【集训队作业2018】喂鸽子 min-max容斥,FFT
原文链接www.cnblogs.com/zhouzhendong/p/UOJ449.html
题解
设 f(i) 表示给 i 只鸽子喂食使得至少一只鸽子被喂饱的期望次数,先 min-max容斥 一下。($\frac ni$ 表示期望每 $\frac ni$ 步喂这 i 只鸽子一次)
$$ans = \sum_{i=1}^n (-1)^{i+1}\binom ni \frac ni \cdot f(i)$$
考虑如何求 f(i) 。假设我们喂饱的是第一只鸽子,那么假设我们喂了其他鸽子 j 次,那么就可以得到以下式子:
$$f(i) = \sum_{j=0}^{\infty} (j+k) \binom {j+k-1}{k-1} \cdot \left ( g^{i-1} \right ) ^{(j)} (0)\cdot \frac 1{i^{j+k}}$$
(注: $h^{(a)}(x)$ 表示函数 $h(x)$ 的 a 阶导数,$h^{(a)}(0)$ 表示指数生成函数 $h$ 的第 a 项系数)
其中 $\left(g^{i-1}\right)^{(j)}(0)$ 表示给 i-1 只鸽子喂食,每只喂的次数不超过 k-1 次,总共喂了 j 次的方案数。由于还有一只要强制喂到 k 次,所以要乘上 $\binom{j+k-1}{k-1}$ ,这种情况下喂了 $j+k$ 次鸽子,所以要乘上 $j+k$。
那么这个 g(x) 是什么东西?
对于一只鸽子,可以喂 $0,1,2,\cdots, k-1$ 次,搞一个指数生成函数就好了。
$$ g(x) = \sum_{i=0}^{k-1} \frac{ x^i} {i!}$$
时间复杂度 $O(n^2k \log (nk))$ 。
好像还有一个 $O(n^2k)$ 的神仙做法,先坑着。
代码
#pragma GCC optimize("Ofast","inline")
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> vi;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=55,K=1005,S=1<<16,mod=998244353;
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
void Del(int &x,int y){
if ((x-=y)<0)
x+=mod;
}
int del(int x,int y){
return x-y<0?x-y+mod:x-y;
}
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=(LL)x*x%mod)
if (y&1)
ans=(LL)ans*x%mod;
return ans;
}
int Fac[S],Inv[S];
void prework(){
int n=S-1;
for (int i=Fac[0]=1;i<=n;i++)
Fac[i]=(LL)Fac[i-1]*i%mod;
Inv[n]=Pow(Fac[n],mod-2);
Fod(i,n,1)
Inv[i-1]=(LL)Inv[i]*i%mod;
}
int C(int n,int m){
if (m<0||m>n)
return 0;
return (LL)Fac[n]*Inv[m]%mod*Inv[n-m]%mod;
}
int n,k;
int m,d,invm;
int f[N];
int R[S],w[S];
int a[S],b[S],c[S];
void FFT(int *a,int n){
For(i,0,m-1)
if (i<R[i])
swap(a[i],a[R[i]]);
for (int t=n>>1,d=1;d<n;d<<=1,t>>=1)
for (int i=0;i<n;i+=d<<1)
for (int j=0;j<d;j++){
int tmp=(LL)w[t*j]*a[i+j+d]%mod;
a[i+j+d]=del(a[i+j],tmp);
Add(a[i+j],tmp);
}
}
int main(){
prework();
n=read(),k=read();
for (m=1,d=0;m<n*k;m<<=1,d++);
invm=Pow(m,mod-2);
For(i,0,m-1)
R[i]=(R[i>>1]>>1)|((i&1)<<(d-1));
w[0]=1,w[1]=Pow(3,(mod-1)/m);
For(i,2,m-1)
w[i]=(LL)w[i-1]*w[1]%mod;
clr(a);
For(i,0,k-1)
a[i]=Inv[i];
FFT(a,m);
For(i,0,m-1)
b[i]=1;
For(x,1,n){
For(i,0,m-1)
c[i]=b[i];
reverse(w+1,w+m);
FFT(c,m);
reverse(w+1,w+m);
For(i,0,m-1)
c[i]=(LL)c[i]*invm%mod*Fac[i]%mod;
f[x]=0;
For(i,0,m-1)
if (c[i])
Add(f[x],(LL)C(i+k-1,k-1)*c[i]%mod*(i+k)%mod*Pow(x,mod-i-k)%mod);
For(i,0,m-1)
b[i]=(LL)b[i]*a[i]%mod;
}
int ans=0;
For(i,1,n){
int tmp=(LL)C(n,i)*n%mod*Pow(i,mod-2)%mod*f[i]%mod;
if (i&1)
Add(ans,tmp);
else
Del(ans,tmp);
}
cout<<ans<<endl;
return 0;
}
UOJ#449. 【集训队作业2018】喂鸽子 min-max容斥,FFT的更多相关文章
- UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp
LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- UOJ #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
- 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
[UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
- UOJ#418. 【集训队作业2018】三角形
#418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...
- UOJ#422. 【集训队作业2018】小Z的礼物
#422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...
- UOJ#428. 【集训队作业2018】普通的计数题
#428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...
- [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥
题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...
- 2019.2.25 模拟赛T1【集训队作业2018】小Z的礼物
T1: [集训队作业2018]小Z的礼物 我们发现我们要求的是覆盖所有集合里的元素的期望时间. 设\(t_{i,j}\)表示第一次覆盖第i行第j列的格子的时间,我们要求的是\(max\{ALL\}\) ...
随机推荐
- linux下python安装
下载包: wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.gz 解压安装: tar -zvxf Python-3.6.3. ...
- docker 基础之监控
docker容器监控命令 docker ps 命令(查看所有的运行中的容器) docker stats 命令(容器状态监控) [root@bogon ~]# docker stats containe ...
- js关联数组
标准javascript 是内含支持hash关联数组,经查找资料并测试,有关标准javascript内含的hash关联数组操作备忘如下 1.Hash关联数组定义 // 定义空数组 myhash = { ...
- js下载后台返回的docx(返回格式:文档流)文件
原文地址: https://www.jianshu.com/p/a81c68c15fbd PS需要指定responseType类型,不然文件内容会乱码哦 咦?文件名乱码?需要手动设置文件名哦↓ 呀,文 ...
- python3列表
Python3 列表 list python的矩阵 python中矩阵可以用双层列表表示 Python列表脚本操作符 len([1, 2, 3]) 3 长度 [1, 2, 3] + [4, 5, 6] ...
- Shell中字符串的切割、拼接、比较、替换
[截取] 一.Linux shell 截取字符变量的前8位,有方法如下: expr substr “$a” 1 8 : 二.按指定的字符串截取 第一种方法: ${varible##*string} # ...
- 游记-HNOI2019
Day -1 最后一场考试依旧没有ak(达成成就:\(\mathrm{OI}\) 生涯 AK 次数仅一次) Day 0 听dalao们说现在做题已经没有意义了,不如多口胡几道题,拓展视野 虽然很抗拒但 ...
- db2数据库备份与恢复
备份 先停掉Tomcat,然后在机器A上执行以下语句: db2stop force db2start db2 force application all db2 backup database pos ...
- Oracle XDB组件重建说明
Oracle XDB 组件重建 说明一. XDB 组件说明1.1 官网说明:XDB 全称XML DB,官网的说明如下:http://docs.oracle.com/cd/E11882_01/appde ...
- Google Python命名规范
Google Python命名规范 module_name, 模块 package_name, 包 ClassName, 类 method_name, 方法 ExceptionName, ...