[ABC267G] Increasing K Times
Problem Statement
You are given an integer sequence of length .
Find the number, modulo , of permutations of such that:
- there exist exactly integers between and (inclusive) such that .
Constraints
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
$N$ $K$ $A_1$ $\ldots$ $A_N$
Output
Print the answer.
Sample Input 1
4 2 1 1 2 2
Sample Output 1
4
Four permutations satisfy the condition: .
Sample Input 2
10 3 3 1 4 1 5 9 2 6 5 3
Sample Output 2
697112
先提一个问题,如果保证给出来的是一个排列,有多少种可能?
考虑从小到大插入数字,这样能保证插入的时候这个数无论在已插入的数的哪里,都是最大的。定义 为插入了前 大的数,此时有 个顺序对的方案数。
这个数有 中方式使答案不变,因为如果他插到了顺序对之间,或者查到了序列的末尾,顺序对数量不变。同理,有 种方式使顺序对数量加一。
那么排列的情况我们会了,不是排列怎么办?如果这个数前面有 个和他一样的,如果他插到了一个和他一样的数的后面,顺序对数量也不会增加。而插入的地方两边一定不是顺序对(至多相等)。所以方程变为
#include<bits/stdc++.h>
using namespace std;
const int N=5005,P=998244353;
int n,k,dp[N][N],c[N],ans,inv[N],iv[N],a[N];//dp[i][j]表示按照从小到大顺序插入,已经插入前i大的数,有j个顺序对
int main()
{
scanf("%d%d",&n,&k);
for(int i=1,x;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
inv[1]=iv[1]=iv[0]=1;
for(int i=1;i<=n;i++)
{
inv[i]=1LL*(P-P/i)*inv[P%i]%P;
iv[i]=iv[i-1]*inv[i]%P;
}
dp[1][0]=1;
for(int i=2,cnt=0;i<=n;i++)
{
if(a[i]==a[i-1])
++cnt;
else
cnt=0;
for(int j=0;j<=k;j++)//
{
dp[i][j]=1LL*dp[i-1][j]*(j+1+cnt)%P;
if(j)
(dp[i][j]+=1LL*dp[i-1][j-1]*(i-j-cnt)%P)%=P;
}
}
ans=dp[n][k];
// printf("%d",ans);
// for(int i=1;i<=n;i++)
// ans=1LL*ans*iv[c[i]]%P;
printf("%d",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通