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;
}