CF1418E Expected Damage

思路

这道题想了好久,没想出来怎么处理a=0后d<b的怪兽的处理方法,最后看了题解,记录一下解法

本题的要求是求出最后受到伤害的期望,我们无法枚举每个排列,计数排列也很困难

可以考虑每个怪兽对伤害的贡献

我们要计算每只怪兽对期望的贡献,就是怪兽的伤害\(\times\)怪兽造成伤害的概率

首先考虑d>=b的怪兽,假设这样的怪兽有x只,则前\(a_i\)只是不能造成伤害的,能造成伤害的只有后\(x-a_i\)只,所以贡献为\(d \times \frac{x-a_i}{x}\)

剩余的d<b的怪兽可以考虑使用插空法,插在x个怪兽中间的x+1个位置中,前\(a_i\)个位置不能造成伤害,所以贡献为\(d \times \frac{x-a_i+1}{x+1}\)

加和即可

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MOD = 998244353;
int n,q,d[200200],a,b,sum[200200];
int pow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)
            ans=(1LL*ans*a)%MOD;
        a=(1LL*a*a)%MOD;
        b>>=1;
    }
    return ans;
}
int main(){
    scanf("%d %d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%d",&d[i]);
    sort(d+1,d+n+1);
    for(int i=1;i<=n;i++)
        sum[i]=(sum[i-1]+d[i])%MOD;
    for(int i=1;i<=q;i++){
        int ans=0;
        scanf("%d %d",&a,&b);
        int pos=lower_bound(d+1,d+n+1,b)-d;
        if(a>n-pos+1){
            printf("0\n");
            continue;
        }
        ans=1LL*((sum[n]-sum[pos-1]+MOD)%MOD)*(1LL*(n-pos+1-a)*pow(n-pos+1,MOD-2)%MOD)%MOD;
        ans=(ans+1LL*(sum[pos-1])*(1LL*(n-pos+2-a)*pow(n-pos+2,MOD-2)%MOD)%MOD)%MOD;
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2020-09-22 09:22  dreagonm  阅读(203)  评论(0编辑  收藏  举报