给定 和字符集大小 以及一个 的排列 ,求有多少个长 ,字符集大小 ,从 开始标号的字符串 满足把 按照 字典序排序后满足 。
即生成的后缀数组是 。
。
首先设 为满足 的数组,即 的排名。
那么观察 和 ,必有 。考虑什么时候能取到等号,显然 时才行。
那么统计出能取等号的位置个数 ,则答案为 。
代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
const int S=400005,p=998244353;
int n,k,a[S],b[S];
int fra[S],inv[S];
inline int qpow(int x,int y)
{
int res=1;
for(;y>0;y>>=1,x=1ll*x*x%p) res=y&1?1ll*res*x%p:res;
return res;
}
inline int C(int n,int m)
{
if(n<m) return 0;
return 1ll*fra[n]*inv[n-m]%p*inv[m]%p;
}
int main()
{
fra[0]=1;
for(int i=1;i<=S-3;i++) fra[i]=1ll*fra[i-1]*i%p;
inv[S-3]=qpow(fra[S-3],p-2);
for(int i=S-3;i>=1;i--) inv[i-1]=1ll*inv[i]*i%p;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[++a[i]]=i;
b[n+1]=0;
int cnt=0;
for(int i=1;i<=n-1;i++) cnt+=b[a[i]+1]<b[a[i+1]+1];
printf("%d\n",C(cnt+k,n));
return 0;
}