CF1569C Jury Meeting

Lisa

这个序列只需要考虑最大值和次大值的数量

如果最大值数量大于1,那么所有排列都可以,输出全排列

如果最大值为1且不等于次大值加1,那么不可能存在

如果最大值为1且等于次大值加1,那么只要最大值后面有至少一个次大值就可行

然后就是组合数学算一算

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int mod=998244353;
int jc[200009];
int n;
int t;
int a[1000001];
int inv[1000001];
int ma,mc,ca,cc;
int x;
long long power(int p,int b,int k){
	long long ans=1;
	while(p){
		if(p&1){
			ans*=b;
			ans%=k;
		}
		b*=b;
		b%=k;
		p/=2;
	}
	return ans%mod;
}
signed main(){
	jc[1]=1;
	jc[0]=1;
	inv[0]=1;
	inv[1]=1;
	for(int i=2;i<=200005;++i){
		jc[i]=jc[i-1]*i%mod;
		inv[i]=power(mod-2,jc[i],mod);
	}
	scanf("%lld",&t);
	while(t--){
		scanf("%lld",&n);
		ma=mc=ca=cc=0;
		for(int i=1;i<=n;++i){
			scanf("%lld",&x);
			if(x>ma){
				ca=ma;
				cc=mc;
				ma=x;
				mc=1;
			}else{
				if(x==ma){
					mc++;
				}else{
					if(x>ca&&x<ma){
						ca=x;
						cc=1;
					}else{
						if(x==ca){
							cc++;
						}
					}
				}
			}
		}
		if(mc>=2){
			printf("%lld
",jc[n]%mod);
			continue;
		}
		if(mc==1){
			if(ma!=ca+1){
				printf("0
");
			}else{
				int ans=jc[n]%mod*inv[cc+1]%mod*inv[n-cc-1]%mod*jc[cc]%mod*cc%mod*jc[n-cc-1]%mod;
				printf("%lld
",ans);
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/For-Miku/p/15249421.html