Codeforces 1528F - AmShZ Farm(转化+NTT+推式子+第二类斯特林数)
神仙题,只不过感觉有点强行二合一(?)。
首先考虑什么样的数组 \(a\) 符合条件,我们考虑一个贪心的思想,我们从前到后遍历,对于每一个 \(a_i\) 如果它已经在前面出现了就不断给它加 \(1\) 直到它没有出现过为止。如果某个 \(a_i\) 超过了 \(n\) 则不符合条件,正确性显然。这样看起来还是有点抽象,我们不妨把它转化成这样的模型:有一架飞机有 \(n\) 个位置,有 \(n\) 个乘客要登飞机,每个乘客都预定了一个位置 \(a_i\),每个乘客上飞机的时候,如果它的位置已经被占了,那么它会一直向前走直到到达一个空位为止并坐下,如果有乘客没位置坐则不符合题意。
这是一个非常经典的问题,仿照那题的解法可以考虑这样的转化:添加一个 \(n+1\) 号位并接链成环(?),将原先在链上走转化为在环上走,那么 \(a\) 符合条件当且仅当 \(n+1\) 位置最后没有被占。由于这 \(n+1\) 个点组成一个环,故 \(n+1\) 个点是对称的,它们被占的概率都是相同的,为 \(\dfrac{1}{n+1}\),因此合法的 \(a\) 的个数就是总序列数乘 \(\dfrac{1}{n+1}\),即 \((n+1)^{n-1}\)(注意:这里我们要做一个微调,即将 \(a_i\) 的上界扩大到 \(n+1\),否则就无法保证每个点都是对称的了,这个 \(\dfrac{1}{n+1}\) 也就不成立了,故总序列个数实际上是 \((n+1)^n\),并且如果 \(\exists a_i=n+1\) 那么肯定就不合法了,因此你改就改呗,也不影响我合法的序列 \(a\) 的个数)。
到这里我们只分析完了序列 \(a\) 的性质,即将序列 \(a\) 的贡献全当作 \(1\) 来算后得到的答案,可实际上对于某个 \(a\) 它对答案的贡献并不是 \(1\),而是 \(\sum\limits_{i=1}^{n+1}c_i^k\),其中 \(c_i\) 为 \(i\) 的出现次数。这时候又到了动用咱们聪明才智的时候了。考虑继续分析 \(a\) 的性质,还是从「\(n+1\) 个点组成一个环」这个条件入手,显然我们将每个点都向右平移 \(C\) 格后每个数的出现次数不变,即合法的 \(b\) 的个数 \(cntb(a)\) 不变,但最后留下来的位置也会跟着平移 \(C\) 格。因此考虑对每个合法的序列 \(a\) 做 \(n\) 次映射,即 \(a_i:=(a_i+C-1)\bmod(n+1)+1\),\(C=1,2,3,\cdots,n\)。由于 \(a\) 是合法的序列,故映射后的序列肯定不是合法序列,显然这 \(n+1\) 个序列的 \(cntb\) 都是相同的,又所有合法序列映射后肯定恰好包含全部序列,因此我们可以求出所有序列的答案之和后除以 \(n+1\) 即可算出答案。
接下来考虑怎么计算所有序列的答案之和,显然每个数的贡献都是相同的,计算出一个数的贡献后乘以 \(n+1\) 即为总贡献,又最后要除掉一个 \(n+1\),他俩刚好怼调了。计算一个数的贡献还算好办,枚举出现次数排列组合求一下即可,即
\]
接下来就是愉快地推式子环节了,至此我们进入了本题的第二部分:
\text{ans}&=\sum\limits_{i=0}^n\dbinom{n}{i}i^kn^{n-i}
\\&=\sum\limits_{i=0}^n\dbinom{n}{i}n^{n-i}\sum\limits_{j=0}^i\begin{Bmatrix}k\\j\end{Bmatrix}j!\dbinom{i}{j}&(\text{第二类斯特林数的性质})
\\&=\sum\limits_{i=0}^n\sum\limits_{j=0}^i\dbinom{n}{i}\dbinom{i}{j}n^{n-i}\begin{Bmatrix}k\\j\end{Bmatrix}j!
\\&=\sum\limits_{i=0}^n\sum\limits_{j=0}^i\dbinom{n}{j}\dbinom{n-j}{i-j}n^{n-i}\begin{Bmatrix}k\\j\end{Bmatrix}j!&(\text{吸收恒等式})
\\&=\sum\limits_{j=0}^n\dbinom{n}{j}\begin{Bmatrix}k\\j\end{Bmatrix}j!\sum\limits_{i=j}^n\dbinom{n-j}{i-j}n^{n-i}&(\text{交换求和号})
\\&=\sum\limits_{j=0}^n\dbinom{n}{j}\begin{Bmatrix}k\\j\end{Bmatrix}j!\sum\limits_{i=0}^{n-j}\dbinom{n-j}{i}n^{n-i-j}·1^i
\\&=\sum\limits_{j=0}^n\dbinom{n}{j}\begin{Bmatrix}k\\j\end{Bmatrix}j!(n+1)^{n-j}
\end{aligned}
\]
\(\begin{Bmatrix}k\\j\end{Bmatrix}\) 可以通过第二类斯特林数·行求出,于是这道二合一的缝合怪题终于做完了(
const int MAXP=1<<18;
const int MAXN=1e5;
const int pr=3;
const int MOD=998244353;
const int ipr=(MOD+1)/3;
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int n,k,rev[MAXP+5],fac[MAXN+5],ifac[MAXN+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
}
void NTT(vector<int> &a,int len,int type){
int lg=31-__builtin_clz(len);
for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<len;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=2;i<=len;i<<=1){
int W=qpow((type<0)?ipr:pr,(MOD-1)/i);
for(int j=0;j<len;j+=i){
for(int k=0,w=1;k<(i>>1);k++,w=1ll*w*W%MOD){
int X=a[j+k],Y=1ll*a[(i>>1)+j+k]*w%MOD;
a[j+k]=(X+Y)%MOD;a[(i>>1)+j+k]=(X-Y+MOD)%MOD;
}
}
}
if(type==-1){
int ivn=qpow(len,MOD-2);
for(int i=0;i<len;i++) a[i]=1ll*a[i]*ivn%MOD;
}
}
vector<int> conv(vector<int> a,vector<int> b){
int LEN=1;while(LEN<a.size()+b.size()) LEN<<=1;
a.resize(LEN,0);b.resize(LEN,0);NTT(a,LEN,1);NTT(b,LEN,1);
for(int i=0;i<LEN;i++) a[i]=1ll*a[i]*b[i]%MOD;
NTT(a,LEN,-1);return a;
}
int main(){
scanf("%d%d",&n,&k);init_fac(k);
vector<int> a(k+1),b(k+1);
for(int i=0;i<=k;i++){
a[i]=(i&1)?(MOD-ifac[i]):ifac[i];
b[i]=1ll*qpow(i,k)*ifac[i]%MOD;
} a=conv(a,b);int cur=1,ans=0;
for(int j=1;j<=min(n,k);j++){
cur=1ll*cur*(n-j+1)%MOD*qpow(j,MOD-2)%MOD;
ans=(ans+1ll*a[j]*fac[j]%MOD*cur%MOD*qpow(n+1,n-j))%MOD;
} printf("%d\n",ans);
return 0;
}
Codeforces 1528F - AmShZ Farm(转化+NTT+推式子+第二类斯特林数)的更多相关文章
- BZOJ5093 图的价值——推式子+第二类斯特林数
原题链接 题解 题目等价于求这个式子 \[ans=n2^{\frac{(n-1)(n-2)}{2}}\sum\limits_{i=0}^{n-1}\binom{n-1}{i}i^k\] 有这么一个式子 ...
- Codeforces 1097G - Vladislav and a Great Legend(第二类斯特林数+树上背包)
Codeforces 题目传送门 & 洛谷题目传送门 首先看到这题我的第一反应是:这题跟这题长得好像,不管三七二十一先把 \(k\) 次方展开成斯特林数的形式,\(f(X)^k=\sum\li ...
- 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数
出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...
- bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 第二类斯特林数展开式: \( S(i,j) = \frac{1}{j!} \sum\l ...
- bzoj 5093 图的价值 —— 第二类斯特林数+NTT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5093 每个点都是等价的,从点的贡献来看,得到式子: \( ans = n * \sum\li ...
- 【BZOJ4555】【TJOI2016】【HEOI2016】求和 (第二类斯特林数+NTT卷积)
Description 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: $$f(n)=\sum_{i=0}^n\sum_{j=0}^i S(i,j)\tim ...
- 【bzoj4555】[Tjoi2016&Heoi2016]求和(NTT+第二类斯特林数)
传送门 题意: 求 \[ f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix} i \\ j \end{Bmatrix}2^jj! \] 思路: 直接将第二类斯特林 ...
- 【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)
题意: 给定\(n\)个点,一个图的价值定义为所有点的度数的\(k\)次方之和. 现在计算所有\(n\)个点的简单无向图的价值之和. 思路: 将式子列出来: \[ \sum_{i=1}^n\sum_{ ...
- BZOJ 4555:[TJOI2016&HEOI2016]求和(第二类斯特林数+NTT)
题目链接 \(Description\) 求 \[\sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj!\]对998244353取模后的结果. \(n<=10^5\) \(Sol ...
随机推荐
- 【二食堂】Beta - Scrum Meeting 7
Scrum Meeting 7 例会时间:5.19 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 文本区域的前后端对接完成,bug已经修复issue2. 自定义关系的添加与删 ...
- BUAA软工-结对项目作业
结对项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目作业 我在这个课程的目标是 通过这门课锻炼软件开发能力和经验,强化与他人合作 ...
- filebeat收集日志到elsticsearch中并使用ingest node的pipeline处理
filebeat收集日志到elsticsearch中 一.需求 二.实现 1.filebeat.yml 配置文件的编写 2.创建自定义的索引模板 3.加密连接到es用户的密码 1.创建keystore ...
- FastAPI 学习之路(三十三)操作数据库
通过创建pydantic模型进行验证提交数据 from pydantic import BaseModel class UserBase(BaseModel): email: str class Us ...
- java中的软,弱,虚引用介绍与特性分析
java的弱,虚,软引用介绍 1.弱,虚,软引用的介绍 对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会 ...
- Celery Task(定时任务)及参数
celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...
- 高频面试题:一张图彻底搞懂Spring循环依赖
1 什么是循环依赖? 如下图所示: BeanA类依赖了BeanB类,同时BeanB类又依赖了BeanA类.这种依赖关系形成了一个闭环,我们把这种依赖关系就称之为循环依赖.同理,再如下图的情况: 上图中 ...
- 认识Linux系统中的inode,硬链接和软链接
在学习和创建软链接遇到了一点问题,总结一下: 在当前文件夹下面建立了两个临时文件夹tempdir1和tempdir2,然后在tempdir2里面创建了一个hello文件,然后用指令ln -s temp ...
- PHP笔记4__函数/全局、静态变量/函数参数/加载函数库/,,
<?php header("Content-type: text/html; charset=utf-8"); echo table(5,5); function table ...
- 使用.NET6打造动态API
ApiLite是直接将Service层自动生成api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0.100-rc ...