正题

题目链接:https://www.luogu.com.cn/problem/P5825


题目大意

对于每个\(k\),求有多少个长度为\(n\)的排列有\(k\)个位置上升。

\(1\leq n\leq 2\times 10^5\)


解题思路

考虑到同时考虑大于和小于十分麻烦,设\(f_i\)表示钦定\(i\)个上升时的方案

连续的上升段可以视为同一个组,那么整个序列就会被分为\(m=n-k\)段,每个组内都是无序的。

所以可以考虑一下\(\text{EGF}\)来做,因为不能选空段,那么每一段的生成函数就是\(e^x-1\)。

也就是\(f_{n-m}=(e^x-1)^m[x^n]\)。二项式定理展开一下

\[f_m=\sum_{i=0}^m\binom{m}{i}(-1)^{m-i}e^{ix}
\]
\[=\sum_{i=0}^m\frac{m!}{i!(m-i)!}(-1)^{m-i}\frac{i^n}{n!}
\]
\[=\frac{m!}{n!}\sum_{i=0}^m\frac{(-1)^{m-i}}{(m-i)!}\frac{i^n}{i!}
\]

\(\text{NTT}\)卷起来就好了。

然后\(g_i\)表示恰好有\(i\)个的话,上二项式反演即可

\[f_i=\sum_{j=0}^i\binom{i}{j}g_j\Rightarrow g_i=\sum_{j=i}(-1)^{j-i}\binom{j}{i}f_j
\]

这个也是显然可以卷积快速求得的。

顺带一提的是,这个求得其实就是欧拉数\(\left\langle\begin{matrix} n\\k\end{matrix}\right\rangle\)

联立上面的\(f_i\)和\(g_i\)的式子可以得到欧拉数的通式

\[\left\langle\begin{matrix} n\\k\end{matrix}\right\rangle=\sum_{i=0}^{n-k}(-1)^{n-k-i}i^n\binom{n+1}{k+j+1}
\]

这个可以一次卷积求得

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=8e5+10,P=998244353;
ll n,m,inv[N],fac[N],f[N],g[N],r[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
void NTT(ll *f,ll op){
for(ll i=0;i<m;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=m;p<<=1){
ll tmp=power(3,(P-1)/p),len=(p>>1);
if(op==-1)tmp=power(tmp,P-2);
for(ll k=0;k<m;k+=p){
ll buf=1;
for(ll i=k;i<k+len;i++){
ll tt=f[i+len]*buf%P;
f[i+len]=(f[i]-tt+P)%P;
f[i]=(f[i]+tt)%P;
buf=buf*tmp%P;
}
}
}
if(op==-1){
ll invn=power(m,P-2);
for(ll i=0;i<m;i++)
f[i]=f[i]*invn%P;
}
return;
}
signed main()
{
scanf("%lld",&n);
inv[1]=1;
for(ll i=2;i<=n;i++)
inv[i]=P-inv[P%i]*(P/i)%P;
inv[0]=fac[0]=1;
for(ll i=1;i<=n;i++)
inv[i]=inv[i-1]*inv[i]%P,fac[i]=fac[i-1]*i%P;
for(ll i=0;i<=n;i++)
f[i]=inv[i]*power(i,n)%P,g[i]=(i&1)?(P-inv[i]):inv[i];
m=1;while(m<=2*n)m<<=1;
for(ll i=0;i<m;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(m>>1):0);
NTT(f,1);NTT(g,1);
for(ll i=0;i<m;i++)f[i]=f[i]*g[i]%P;
NTT(f,-1);
memset(g,0,sizeof(g));
for(ll i=0;i<m;i++)
f[i]=(i<n)?(f[i+1]*fac[i+1]%P):0;
for(ll i=n;i<m;i++)f[i]=0;
for(ll i=0;i<n;i++){
f[i]=f[i]*fac[n-i-1];
f[i]=(i&1)?(P-f[i]):f[i];
g[i]=inv[i];
}
NTT(f,1);NTT(g,1);
for(ll i=0;i<m;i++)f[i]=f[i]*g[i]%P;
NTT(f,-1);
for(ll i=0;i<n-i-1;i++)swap(f[i],f[n-i-1]);
for(ll i=0;i<n;i++){
f[i]=f[i]*inv[i]%P;
f[i]=((n-i)&1)?f[i]:(P-f[i]);
printf("%lld ",f[i]%P);
}
putchar('0');
return 0;
}

P5825-排列计数【EGF,NTT】的更多相关文章

  1. BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 911  Solved: 566[Submit][Status ...

  2. bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)

    题目链接: 4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 846  Solved: 530[Submit][ ...

  3. ACM/ICPC 之 DP-浅谈“排列计数” (POJ1037)

    这一题是最近在看Coursera的<算法与设计>的公开课时看到的一道较难的DP例题,之所以写下来,一方面是因为DP的状态我想了很久才想明白,所以借此记录,另一方面是看到这一题有运用到 排列 ...

  4. 数学(错排):BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status ...

  5. 【数论·错位排列】bzoj4517 排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1428  Solved: 872[Submit][Statu ...

  6. BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]

    4517: [Sdoi2016]排列计数 题意:多组询问,n的全排列中恰好m个不是错排的有多少个 容斥原理强行推♂倒她 $恰好m个不是错排 $ \[ =\ \ge m个不是错排 - \ge m+1个不 ...

  7. BZOJ 2111: [ZJOI2010]Perm 排列计数 [Lucas定理]

    2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1936  Solved: 477[Submit][ ...

  8. bzoj4517排列计数 错排+组合

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1491  Solved: 903[Submit][Statu ...

  9. BZOJ_4517_[Sdoi2016]排列计数_组合数学

    BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...

  10. 2111: [ZJOI2010]Perm 排列计数

    2111: [ZJOI2010]Perm 排列计数 链接 题意: 称一个1,2,...,N的排列$P_1,P_2...,P_n$是Magic的,当且仅当$2<=i<=N$时,$P_i> ...

随机推荐

  1. SpringCache(redis)

    pom <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr ...

  2. WPF教程(四)RelativeSource属性

    我们进行Bingding时,如果明确知道数据源的Name,就能用Source或者ElementName进行绑定,但是有时候我们需要绑定的数据源可能没有明确的Name,此时我们就需要利用Bingding ...

  3. react的每个方法为什么一定要bind this

    一开始学习react的时候就了解了react的每个方法都要bind(this)或者使用箭头函数绑定this的指向,到底是为什么要这么写呢,当时要学习的东西太多了就没在意,今天特别好奇(不搞懂不吃饭的态 ...

  4. Ubuntu下 QT中配置ROS-Kinetic

    打开qtcreater自动加载ros环境,通过修改*.desktop文件 gedit ~/.local/share/applications/qtcreator.desktop 将其中Exec=XXX ...

  5. PowerDotNet平台化软件架构设计与实现系列(01):基础数据平台

    本系列我将主要通过图片和少许文字讲解通过个人自研的PowerDotNet进行快速开发平台化软件产品. PowerDotNet不仅仅是包含像Newtonsoft.Json.Dapper.Quartz.R ...

  6. C#窗体间互相传值

    Demo窗体图片,Form1 Demo窗体图片,Form2 公共委托 using System; namespace _DeleFrm{  public class Dele  {    public ...

  7. jenkins AWS CodeDeploy不停机部署

    此项目的特点是把Jenkins与CodeDeploy相结合做的CICD做的蓝绿发布,CI与CD 是分开的,CI构建完以后以BuildNumber的形式把war包存至AWS的S3桶中.同时在java项目 ...

  8. set类型数据的操作指令

    集合无序,无下标. 1. 也可以在集合上继续添加元素. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.

  9. Spring5(六)——AspectJ(xml)

    一.AspectJ 1.介绍 AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,也可以说 AspectJ 是一个基于 Java 语言的 AOP 框架.通常我们在 ...

  10. awk工作流程

    awk 工作过程:先执行BEGIN模块,再跟文本交互,最后执行END模块.也就是说BEGIN/END模块,这俩是单独操作跟文本是同一级,但执行有优先级,BEGIN模块>文本>END模块 行 ...