P5011

题目传送门

看似很难,实则一点都不简单

因为模数找到的这个题,黑色的数字越看越红。

我们可以把单独一个动作的贡献和组合技的贡献拆开分别计算期望。这样根据期望的线性性,总期望就是两个期望累加。

先看单独一个动作的贡献总和的期望:

下面记\(sum=\sum\limits_{i=1}^{k} {a_i}\)

某个位置出现第\(i\)种动作的概率是\(\frac 1k\),所以这个位置的贡献期望为\(\frac 1k \times sum\),共有n个位置,所以这部分的总期望为\(\frac nk \times sum\)

接下来是组合技的贡献总和的期望:

刚才我们说过某个位置出现第\(i\)种动作的概率是\(\frac 1k\),所以某个位置出现\(i、i+1\)\(i=k\)时为\(k、1\))组合技的概率就是\(\frac {1}{k^2}\)。那么这个位置出现组合技的期望就是\(\sum\limits_{i=1}^{k}{a_i+a_{ (i+1) mod k} } \times \frac {1}{k^2}\)

我们化简一下上面的式子,由于每个动作\(i\)都会在上面的累加中被统计两次,所以每个位置出现组合技的期望又可以写做\(sum \times \frac {2}{k^2}\)。共有\(n-1\)个位置可以出组合技,所以这部分的期望就是\((n-1) \times sum \times \frac {2}{k^2}\)

将两部分期望相加就是答案。

至于如何求一个分数的mod,也是很好理解的:将分子/分母变成分子*inv(分母)。(不然这个题为什么要给求逆元代码)

最后就是这个很毒瘤的n的取值范围。。。这个时候就体现出快读的好处了,可以一边读入一边取模,具体怎么操作,每次x=x*10+c-'0'时将x取模就好了。

\(\color{red}{祝愿我们伟大的祖国繁荣昌盛!在此提前祝贺祖国母亲76岁生日快乐!}\)

代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int mod=19491001;
const int N=1e6+6;

inline int read(){
	int x=0;char c=getchar();
	while(c<48) c=getchar();
	while(c>47) x=(((x<<1)+(x<<3))%mod+(c^48))%mod,c=getchar();
	return x;
}

int n,k,a[N],ans1,ans2,sum;

inline int qpow(int x,int y){
	int ans=1;
	while(y){
		if(y&1) ans=(ans*x)%mod;
		x=(x*x)%mod;y>>=1;
	}
	return ans;
}

inline int inv(int x){
	return qpow(x,mod-2);
}

signed main(){
	n=read(),k=read();
	for(int i=1;i<=k;i++){
		a[i]=read();
		sum=(sum+a[i])%mod; 
	}
	ans1=n*sum%mod*inv(k)%mod;
	ans2=2*sum%mod*((n-1)%mod+mod)%mod*inv(k*k%mod)%mod;
	printf("%lld",(ans1+ans2)%mod);
	return 0;
}
posted @ 2025-08-13 16:33  qwqSW  阅读(8)  评论(0)    收藏  举报