Description

如果对于一个 \(1\sim n\) 的排列满足:

在 \(1\sim n-1\) 这些位置之后将序列断开,使得总可以从右边找一个数,使得该数不会比左边所有数都大,则称该序列是“美妙的”。

给出 \(n\) ,求出长度为 \(n\) 的美妙的序列的数量。多组数据。 \(T,n\leq 10^5\)。对 \(998244353\) 取模。

Solution

暴力DP是 \(O(Tn^2)\) 的。我们需要发现题目的隐藏性质。

如果某个排列不是美妙的,那一定存在一个位置 \(k\) ,使得 \(k\) 右边的最小值大于左边的最大值。也就是说,\(k\) 左边是一个 \(1\sim k\) 的排列。

问题就转化成了求有多少长度为 \(n\) 的排列,使得任意一个前缀都不是 \(1\sim k\) 的排列。

考虑 \(DP\) 。设 \(f[i]\) 表示长度为 \(i\) 的美妙的排列个数。有转移:

\[f[n]=n!-\sum_{i=1}^{n-1}i!\cdot f[n-i]\quad f[0]=0
\]

这个转移的含义是用总方案数减去不合法的方案数,也就是减去所有不美妙的排列。于是枚举最靠右不能满足要求的位置,然后把序列划分成两端。前一段是一个 \(1\sim k\) 的排列,后一段一定是一个美妙的序列(不然一定可以找到一个更靠右的不满足题意的位置)。

这时候就可以分治FFT了。但是别着急,一般分治FFT能做的多项式求逆都可以做。再推几步式子:

\[f[n]=n!-\sum_{i=1}^n i!\cdot f[n-i]
\]

移项:

\[\sum_{i=0}^n i!\cdot f[n-i]=n!
\]

由于有 \(f[0]=0\) 的特殊情况所以需要特殊考虑:

\[\text{当n=0时}\quad \sum_{i=0}^n i!\cdot f[n-i]+1=n!
\]

于是令 \(F\) 为 \(f\) 的生成函数,\(G=\sum\limits_{i=0}^\infty i!\cdot x^i\),于是就有 \(F\times G+1=G\),移项可以得到:

\[F=1-\frac1{G}
\]

多项式求逆即可。复杂度 \(O(n\log n)\)。

Code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
#define int long long
const int n=1e5;
const int N=4e5+5;
const int mod=998244353; int fac[N];
int tmpa[N];
int b[N],c[N];
int lim,rev[N]; int getint(){
int X=0,w=0;char ch=getchar();
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
} int ksm(int a,int b=mod-2,int ans=1){
while(b){
if(b&1) ans=ans*a%mod;
a=a*a%mod;b>>=1;
} return ans;
} void ntt(int *f,int opt){
for(int i=1;i<lim;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);
for(int mid=1;mid<lim;mid<<=1){
int tmp=ksm(3,(mod-1)/(mid<<1));
if(opt<0) tmp=ksm(tmp);
for(int R=mid<<1,j=0;j<lim;j+=R){
int w=1;
for(int k=0;k<mid;k++,w=w*tmp%mod){
int x=f[j+k],y=w*f[j+k+mid]%mod;
f[j+k]=(x+y)%mod,f[j+k+mid]=(mod+x-y)%mod;
}
}
} if(opt<0)
for(int in=ksm(lim),i=0;i<lim;i++) f[i]=f[i]*in%mod;
} void solveinv(int len,int *a,int *b){
if(!len) return b[0]=ksm(a[0]),void();
solveinv(len>>1,a,b);lim=len+len;
for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
for(int i=0;i<len;i++) tmpa[i]=a[i];
ntt(tmpa,1),ntt(b,1);
for(int i=0;i<lim;i++) b[i]=b[i]*(2ll-tmpa[i]*b[i]%mod+mod)%mod;
ntt(b,-1);
for(int i=len;i<lim;i++) b[i]=0;
for(int i=0;i<lim;i++) tmpa[i]=0;
} signed main(){
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
solveinv(131072,fac,b);
for(int i=1;i<=n;i++) b[i]=mod-b[i];
int T=getint();
while(T--){
int x=getint();
printf("%lld\n",b[x]);
} return 0;
}

[51nod1514] 美妙的序列的更多相关文章

  1. Solution -「51nod 1514」美妙的序列

    \(\mathcal{Description}\)   Link.   称排列 \(\{p_n\}\) 美妙,当且仅当 \((\forall i\in[1,n))(\max_{j\in[1,i]}\{ ...

  2. NTT【51nod】1514 美妙的序列

    题意:1~n 的全排列中,有多少个排列满足任意从中间切成两段后,左边段的最大值大于右边段的最小值? 例如:n为3时有3种 2 3 1 3 1 2 3 2 1 解释:比如 2 3 1 (2) (3 1) ...

  3. 【51nod 1514】 美妙的序列

    题目 我们发现我们得正难则反 还是设\(f_i\)表示长度为\(i\)的序列个数 考虑容斥 \[f_i=i!-\sum_{j=1}^{i-1}f_j(i-j)!\] \(i!\)显然是总方案数,我们减 ...

  4. 51nod 1514 美妙的序列

    Description 长度为n的排列,且满足从中间任意位置划分为两个非空数列后,左边的最大值>右边的最小值.问这样的排列有多少个%998244353 题面 Solution 正难则反 \(f[ ...

  5. 51nod 1514 美妙的序列 分治NTT + 容斥

    Code: #include<bits/stdc++.h> #define ll long long #define mod 998244353 #define maxn 400000 # ...

  6. 模拟赛1101d1

    完美的序列(sequence)Time Limit:1000ms Memory Limit:64MB题目描述LYK 认为一个完美的序列要满足这样的条件:对于任意两个位置上的数都不相同.然而并不是所有的 ...

  7. 济南学习 Day 4 T1 am

    完美的序列(sequence)Time Limit:1000ms Memory Limit:64MB题目描述LYK 认为一个完美的序列要满足这样的条件:对于任意两个位置上的数都不相同.然而并不是所有的 ...

  8. 11.1 morning

    完美的序列(sequence)Time Limit:1000ms Memory Limit:64MB题目描述LYK 认为一个完美的序列要满足这样的条件:对于任意两个位置上的数都不相同.然而并不是所有的 ...

  9. 【CODEVS 6384 大米兔学全排列】

    ·大米兔学习全排列,还有一些逆序对,还有一棵二叉索引树.· ·分析:       首先肯定不是像题目上说的那样,使用next_permutation去完成这道题,因为就算是线性的它也不能承受庞大的排列 ...

随机推荐

  1. uni-app开发一次,覆盖多端的前端框架

    uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台. 一套代码,运行多个平台 uni-app实现了一套代码, ...

  2. CDH版本的hadoop下载

    http://archive.cloudera.com/cdh5/cdh/5/加要下载的cdh版本插件 例如: http://archive.cloudera.com/cdh5/cdh/5/zooke ...

  3. VsCode编写和调试.NET Core

    本文转自:https://www.cnblogs.com/Leo_wl/p/6732242.html 阅读目录 使用VsCode编写和调试.NET Core项目 回到目录 使用VsCode编写和调试. ...

  4. 配置微信jssdk自定义分享

    前段时间做这个功能的时候遇到这个问题,之前的话是微信自动抓取界面第一张图,现在微信更新api,必须自行配置,接入jssdk,才能实现该功能. 详细可以查看微信的jssdk文档 微信官方开发者文档    ...

  5. Release file is expired, Updates for this repository will not be applied.(资源索引文件过期问题)

    将Debian下载源同步到本地之后,通过本地资源地址进行apt update操作时提示过期问题: E: Release file for http://localhost/security/dists ...

  6. Codeforces Round #485 (Div. 2) A. Infinity Gauntlet

    Codeforces Round #485 (Div. 2) A. Infinity Gauntlet 题目连接: http://codeforces.com/contest/987/problem/ ...

  7. DL_1_week2_神经网络基础

    二分类问题 在二分分类问题中,目标是训练出一个分类器,这里以图片特征向量x作为输入,预测输出的结果标签y是1还是0,也就是预测图片中是否有猫.          计算机保存一张图片(彩色),要保存三个 ...

  8. Delphi fmx控件在手机滑动与单击的问题

    Delphi fmx控件在手机滑动与单击的问题 (2016-03-08 10:52:00) 转载▼ 标签: it delphi 分类: Delphi10 众所周知,fmx制作的app,对于象TEdit ...

  9. zookeeper配置文件共享中心

    最近频繁的系统上线,每次打包都要把配置文件替换为正式环境的配置文件,虽然说就是复制粘贴的事,架不住文件杂乱,而且多. 期初的想法是有没有办法将配置文件与系统隔离开来,这样在更新时候,就只需要更新代码部 ...

  10. ASP.NET Core 请求/查询/响应参数格式转换(下划线命名)

    业务场景: 在 ASP.NET Core 项目中,所有的代码都是骆驼命名,比如userName, UserName,但对于 WebApi 项目来说,因为业务需要,一些请求.查询和响应参数的格式需要转换 ...