Educational Codeforces Round 113 (Rated for Div. 2) C. Jury Meeting

题意
找到一种序列,按序减一,如果没有出现同一个位置连续减两次,即为good,问一共有多少种。
思路
设max 最大值的个数, min次大值的个数
情况1:有大于或等于两个最大值,那任意排都可
情况2:max-min== 0 ,任意排都可
情况3:若max-min==1 那必须保持最大值不能在最后,不然会出现连减两次,
那也就是要最后一个次大值之后不能有最大值。设cnt为次大值的个数,那满足的这种要求的序列的概率为 cnt / (cnt+1);即不要排在最后即可。
代码

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<string,string>pss;
typedef pair<int,int> pii;
const ll mod=998244353;
#define mem(a,n) memset(a,n,sizeof a)
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
const int inf=0x3f3f3f3f;
const int N =5e5+7;
ll gcd(ll a,ll b){ll d; while(b){ d=b; b=a%b; a=d; } return a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const ll MOD = 998244353;     
const ll MAXN = 5e5 + 3;
ll fac[MAXN];       
ll inv[MAXN];       
ll QPow(ll x, ll n){
    ll ret = 1;
    ll tmp = x % MOD;
    while (n){
        if (n & 1){
            ret = (ret * tmp) % MOD;
        }
        tmp = tmp * tmp % MOD;
        n >>= 1;
    }
    return ret;
}
void init(){
    fac[0] = 1;
    for (int i = 1; i < MAXN; i++){
        fac[i] = fac[i - 1] * i % MOD;
    }
    inv[MAXN - 1] = QPow(fac[MAXN - 1], MOD - 2);
    for (int i = MAXN - 2; i >= 0; i--){
        inv[i] = inv[i + 1] * (i + 1) % MOD;
    }
}
int a[N];
map<int,int>mp;
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;cin>>t;
    init();
    while(t--){
        mp.clear();
        int n;cin>>n;
        rep(i,1,n){
            cin>>a[i];
            mp[a[i]]++;
        }
        sort(a+1,a+n+1);
        if(mp[a[n]]>=2){
            cout<<fac[n]<<endl;
        }
        else if(a[n]==a[n-1]){
            cout<<fac[n]<<endl;
        }
        else if(a[n]-a[n-1]==1){
            ll ans=fac[n];
            ans=(ans*mp[a[n-1]])%mod*QPow(mp[a[n-1]]+1,MOD-2)%MOD;
            cout<<ans%MOD<<endl;
        }
        else cout<<"0"<<endl;
        
    }
    
}
    




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值