CF1983E I Love Balls
题意
\(n\) 个小球,有 \(k\) 个特殊小球,两个人轮流随机拿,每个小球有权值,如果拿到特殊球就再拿一个,问两个人的期望得分。
题解
关键1
如果没有特殊小球,那么每个球是等价的,计算期望的时候可以直接用平均值作为一个小球的权值,把每个小球的权值都看成平均值
关键2
把拿取操作看成一个序列,不管有没有特殊小球,非特殊小球一定第奇数个属于 \(A\),第偶数个属于 \(B\)。于是可以先求出非特殊小球的贡献,即 \(\lceil\frac {num}2\rceil\cdot \frac{sum}{num}\)
关键3
对于特殊小球,它的从属和下一个球一样,可以认为是非特殊小球把拿取序列分成了\(n-k+1\) 个区间,奇数区间给 \(A\),偶数区间给 \(B\)。对于特殊小球的处理也是一样的,用平均值计算。假设有 \(m\) 个区间,那么一个特殊小球分到奇数区间的概率就是 \(\frac{\lceil\frac m2\rceil}m\),所以分给 \(A\) 的小球期望个数就是再乘上 \(num\) 。
最后答案就是两个贡献加起来
#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void Read(T &n){
char ch; bool flag=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(n=(ch^48);isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48));
if(flag)n=-n;
}
typedef long long ll;
const int MOD = 1000000007;
const int MAXN = 400005;
inline int inc(int a, int b){a+=b;if(a>=MOD)a-=MOD;return a;}
inline int dec(int a, int b){a-=b;if(a<0)a+=MOD;return a;}
inline void iinc(int &a, int b){a=inc(a,b);}
inline void ddec(int &a, int b){a=dec(a,b);}
inline void upd(int &a, ll b){a=(a+b)%MOD;}
inline int ksm(int base, int k=MOD-2){
int res = 1;
while(k){
if(k&1) res = 1ll*res*base%MOD;
base = 1ll*base*base%MOD;
k >>= 1;
}
return res;
}
int a[MAXN];
int main(){
// freopen("1.in","r",stdin);
int T; Read(T);
while(T--){
int n, k;
Read(n); Read(k);
for(int i=1; i<=n; i++) Read(a[i]);
int sm1=0, sm2=0, sm=0;
for(int i=1; i<=k; i++) iinc(sm1,a[i]);
for(int i=k+1; i<=n; i++) iinc(sm2,a[i]);
sm = inc(sm1,sm2);
sm1 = 1ll*sm1*ksm(k)%MOD;
sm2 = 1ll*sm2*ksm(n-k)%MOD;
int res = (1ll*sm2*((n-k+1)/2)+1ll*sm1*((n-k+1+1)/2)%MOD*ksm(n-k+1)%MOD*k)%MOD;
printf("%d %d\n",res,dec(sm,res));
}
return 0;
}