原文链接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);elseDel(ans,tmp);}cout<<ans<<endl;return 0;
}

  

转载于:https://www.cnblogs.com/zhouzhendong/p/UOJ449.html

UOJ#449. 【集训队作业2018】喂鸽子 min-max容斥,FFT相关推荐

  1. P3175 [HAOI2015]按位或(Min - Max容斥,FMT,概率期望,全网最清晰的题解!)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/P3175 Prob ...

  2. UOJ#449. 【集训队作业2018】喂鸽子

    #449. [集训队作业2018]喂鸽子 DP好题 法一:min-max容斥 处理前m个,最快吃饱的鸽子期望的时间 根据期望的定义 考虑每个方案数的概率*期望次数 枚举前m个用了x个,概率都是(1/m ...

  3. uoj#422. 【集训队作业2018】小Z的礼物

    uoj#422. [集训队作业2018]小Z的礼物 题目描述 Solution 所有礼物全部取到的方案数并不好求,因此我们考虑min−maxmin-maxmin−max容斥,转化为第一次取到集合中某一 ...

  4. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  5. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

  6. [集训队作业2018]小Z的礼物(min-max容斥,插头dp)

    传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...

  7. 【集训队作业2018】喂鸽子

    我的计数还是太差了-- 这道题现在知道三种做法. 1. 直接DP 首先显然需要min-max容斥(不知道请百度),不然很难算. 显然对于大小相同的集合答案一样,问题转化为求 \(f_c\) 即 \(c ...

  8. 【UOJ 429】串串划分(Runs)(容斥)+ 有关 Lyndon Tree 及其应用的小小记录

    串串划分 题目链接:UOJ 429 题目大意 给你一个字符串,然后问你有多少个划分,满足相邻的两个串不相等,且每个串都不存在整周期. 思路 Lyndon Tree L y n d o n T r e ...

  9. 2018.8.4T3(大容斥)

    描述 蔡老板得到了一块 N * N 的方格,我们用 (x,y) 表示里面第 x 行第 y 列的房子 (1<=x,y<=N). 现在蔡老板要在上面盖 N 间房子,盖房子要满足以下几个条件: ...

最新文章

  1. LISP 图层前后缀_lisp获取qleader端点_lisp以一个图层来做定义快名称怎么实现
  2. 浏览器页面有哪三层构成,分别是什么,作用是什么
  3. java 读写文件[多种方法]
  4. matlab 求x y关系,怎么用MATLAB建立数据间的函数关系
  5. STM32:Flash擦除与读写操作(HAL库)
  6. org.apache.poi 读取数字问题
  7. 文本内容之间的关键词提取和相似度计算
  8. matlab实验函数编写与程序设计,matlab实验四函数编写与程序设计.doc
  9. 换手率与股价成交量 关系
  10. mysql循环更新_MySql多表循环遍历更新
  11. Python语言基础
  12. 捷联惯导算法 matlab,捷联惯导算法与组合导航原理资料及更正
  13. Java中JCP, JEP, JLS, JSR是什么
  14. ds18b20工作原理和测温原理介绍
  15. selenium 轻松模拟登录企查查,获取企业详细信息链接
  16. hdoj4826Labyrinth【dp】
  17. 热加工作业考研题目答案分享——metal casting 1
  18. c语言还是python-自学编程应该从c语言还是python入手?
  19. 举个栗子!Tableau 技巧(139):突出显示文本表的行或列
  20. 目标检测20年(Object Detection in 20 Years)

热门文章

  1. 使用OpenSSL为支付宝生成RSA私钥
  2. 读书笔记之《程序员必读的职业规划书》
  3. LigerUi之Grid使用详解(二)——数据编辑
  4. HDU 2176(Nim博弈)
  5. Linux游戏0 A.D.操作说明(持续更新中)
  6. Spark中Data skew(数据倾斜)Java+Python+Scala三种接口完整代码
  7. 4.4 高斯消元法的矩阵表示
  8. 深度学习(四十三)——深度强化学习(6)AlphaGo全系列
  9. kafka to mysql_Flink : kafka to mysql example
  10. hive 元数据 自定义_Hive中的用户自定义函数