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;
}
posted @ 2024-07-15 16:38  oisdoaiu  阅读(9)  评论(0编辑  收藏  举报