ABC 295

发布时间 2023-03-26 21:59:47作者: SFlyer

没有更完。

赛后的补题,所以懒得做 \(\text{A}\sim\text{D}\)

E

首先,一个错误的思路。

考虑 \(A_k\) 是原先 \(A_i\neq 0\) 中的一个,还是 \(A_i\) 转化成 \(0\) 后的一个。前者没有任何问题,但是后者会重复 \(\rightarrow\) 错误!

正确的思路:

注意到 \(\text{Answer}=\displaystyle \sum^{m}_{i=1} \ ([\text{possibility of }A_k=i]\times i)=\sum^{m}_{i=1}\ [\text{possibility of}A_k\ge i]\)

这个证明是很显然的。

再次注意到 \(N,M\le 2000\rightarrow\) 可以用 \(O(NM)\)

Spoiler

考虑枚举 \(i\),然后 \(O(N)\) 计算 \(\sum\) 后面的答案。其实,\([\text{possibility of}A_k\ge i]\) 就等于 \([\text{possibility of at least } N-k+1 \text{ integers that are } \ge i]\)。这样,就很简单了。

Code
#include <bits/stdc++.h>

using namespace std;

#define de(x) cout<<#x<<"="<<x<<endl

#define int long long

const int N = 2e3+3;
const int mod = 998244353;

int inv(int a){
	return a==1?1:(mod-1ll*inv(mod%a)*(mod/a)%mod);
}

int n,m,k;
int a[N];
int binom[N][N];

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin>>n>>m>>k;
    for (int i=0; i<n; i++){
        cin>>a[i];
    }
    binom[0][0]=1;
    for (int i=1; i<N; i++){
        binom[i][0]=1;
        for (int j=1; j<=i; j++){
            binom[i][j]=binom[i-1][j]+binom[i-1][j-1];
            binom[i][j]%=mod;
        }
    }
    int zero=0;
    for (int i=0; i<n; i++){
        zero+=(a[i]==0);
    }
    int ans=0;
    for (int i=1; i<=m; i++){
        // count the number of ways such that a_k>=i
        int nd=n-k+1;
        for (int j=0; j<n; j++){
            if (a[j]>=i){
                nd--;
            }
        }
        if (nd<0){
            ans++;
            ans%=mod;
            continue;
        }
        if (nd>zero){
            continue;
        }
        int pos=(m-i+1)*inv(m)%mod;
        int pos2=(1-pos+mod)%mod;
        vector<int> v1(zero+1),v2(zero+1);
        v1[0]=1;
        v2[0]=1;
        for (int j=0; j<zero; j++){
            v1[j+1]=v1[j]*pos;
            v1[j+1]%=mod;
            v2[j+1]=v2[j]*pos2;
            v2[j+1]%=mod;
        }
        for (int j=nd; j<=zero; j++){
            ans+=v1[j]*v2[zero-j]%mod*binom[zero][j]%mod;
            ans%=mod;
        }
    }
    cout<<ans<<endl;
    return 0;
}