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

神仙题,只不过感觉有点强行二合一(?)。

首先考虑什么样的数组 \(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}
\]

接下来就是愉快地推式子环节了,至此我们进入了本题的第二部分:

\[\begin{aligned}
\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+推式子+第二类斯特林数)的更多相关文章

  1. BZOJ5093 图的价值——推式子+第二类斯特林数

    原题链接 题解 题目等价于求这个式子 \[ans=n2^{\frac{(n-1)(n-2)}{2}}\sum\limits_{i=0}^{n-1}\binom{n-1}{i}i^k\] 有这么一个式子 ...

  2. Codeforces 1097G - Vladislav and a Great Legend(第二类斯特林数+树上背包)

    Codeforces 题目传送门 & 洛谷题目传送门 首先看到这题我的第一反应是:这题跟这题长得好像,不管三七二十一先把 \(k\) 次方展开成斯特林数的形式,\(f(X)^k=\sum\li ...

  3. 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数

    出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...

  4. bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 第二类斯特林数展开式: \( S(i,j) = \frac{1}{j!} \sum\l ...

  5. bzoj 5093 图的价值 —— 第二类斯特林数+NTT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5093 每个点都是等价的,从点的贡献来看,得到式子: \( ans = n * \sum\li ...

  6. 【BZOJ4555】【TJOI2016】【HEOI2016】求和 (第二类斯特林数+NTT卷积)

    Description 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: $$f(n)=\sum_{i=0}^n\sum_{j=0}^i S(i,j)\tim ...

  7. 【bzoj4555】[Tjoi2016&Heoi2016]求和(NTT+第二类斯特林数)

    传送门 题意: 求 \[ f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix} i \\ j \end{Bmatrix}2^jj! \] 思路: 直接将第二类斯特林 ...

  8. 【bzoj5093】[Lydsy1711月赛]图的价值(NTT+第二类斯特林数)

    题意: 给定\(n\)个点,一个图的价值定义为所有点的度数的\(k\)次方之和. 现在计算所有\(n\)个点的简单无向图的价值之和. 思路: 将式子列出来: \[ \sum_{i=1}^n\sum_{ ...

  9. BZOJ 4555:[TJOI2016&HEOI2016]求和(第二类斯特林数+NTT)

    题目链接 \(Description\) 求 \[\sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj!\]对998244353取模后的结果. \(n<=10^5\) \(Sol ...

随机推荐

  1. 【二食堂】Beta - Scrum Meeting 7

    Scrum Meeting 7 例会时间:5.19 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 文本区域的前后端对接完成,bug已经修复issue2. 自定义关系的添加与删 ...

  2. BUAA软工-结对项目作业

    结对项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目作业 我在这个课程的目标是 通过这门课锻炼软件开发能力和经验,强化与他人合作 ...

  3. filebeat收集日志到elsticsearch中并使用ingest node的pipeline处理

    filebeat收集日志到elsticsearch中 一.需求 二.实现 1.filebeat.yml 配置文件的编写 2.创建自定义的索引模板 3.加密连接到es用户的密码 1.创建keystore ...

  4. FastAPI 学习之路(三十三)操作数据库

    通过创建pydantic模型进行验证提交数据 from pydantic import BaseModel class UserBase(BaseModel): email: str class Us ...

  5. java中的软,弱,虚引用介绍与特性分析

    java的弱,虚,软引用介绍 1.弱,虚,软引用的介绍 对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会 ...

  6. Celery Task(定时任务)及参数

    celery beat 是一个调度器:它以常规的时间间隔开启任务,任务将会在集群中的可用节点上运行. 默认情况下,入口项是从 beat_schedule 设置中获取,但是自定义的存储也可以使用,例如在 ...

  7. 高频面试题:一张图彻底搞懂Spring循环依赖

    1 什么是循环依赖? 如下图所示: BeanA类依赖了BeanB类,同时BeanB类又依赖了BeanA类.这种依赖关系形成了一个闭环,我们把这种依赖关系就称之为循环依赖.同理,再如下图的情况: 上图中 ...

  8. 认识Linux系统中的inode,硬链接和软链接

    在学习和创建软链接遇到了一点问题,总结一下: 在当前文件夹下面建立了两个临时文件夹tempdir1和tempdir2,然后在tempdir2里面创建了一个hello文件,然后用指令ln -s temp ...

  9. PHP笔记4__函数/全局、静态变量/函数参数/加载函数库/,,

    <?php header("Content-type: text/html; charset=utf-8"); echo table(5,5); function table ...

  10. 使用.NET6打造动态API

    ApiLite是直接将Service层自动生成api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0.100-rc ...