2020 2.2【lxs Contest #93】

https://file.floj.tech/export/SadZyRlqWwTcRi2EnHYC

t1 beijing.

70分做法,f[i][j]表示甲还剩i场赢,乙还剩j场赢,此时应该已经赢了f[i][j]元,易得f[i][j]=(f[i-1][j]+f[i][j-1])/2。边界条件f[i][0]=-2^(2n-1),f[0][i]=2^(2n-1)。

100分做法,发现结论,此时甲的胜率为p,打完一把后甲的胜率为p+q或p-q,则这场比赛就下注2*q*2^(2n-1)。

大概就是一开始胜率为50,你要使他到100时下注了2^(2n-1),故每一次就是那么多。

f[i][t]表示甲还剩i场,总共要打t场,甲的胜率。

f[i][t]=\frac{2^{t}-\sum \binom{t}{j}}{2^{t}}。

f不可求,但是发现了设甲还差x场,乙还差y场,此时f[x-1][x+y-2]-f[x][x+y-2]=2q=\frac{\binom{x+y-2}{x-1}}{2^{x+y-2}}。

这就可求了,顺道求过去就可以了。

代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mo=1e9+7;
const int N=200005;
int n,jc[N],niy[N];
inline int read()
{
    char c=getchar();
    int x=0,f=1;
    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)) {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return x*f;
}
inline int hapow(int x,int y)
{
    int daan=1;
    while(y)
    {
        if(y&1) daan=(daan*x)%mo;
        y>>=1;
        x=(x*x)%mo;
    }
    return daan;
}
inline int c(int x,int y)
{
    return jc[x]*niy[y]%mo*niy[x-y]%mo;
}
int er[N];
signed main()
{
    n=read();
    jc[0]=1;er[0]=1;for(int i=1;i<=n*2;i++) jc[i]=(jc[i-1]*i)%mo;
    for(int i=1;i<=n*2;i++) niy[i]=hapow(i,mo-2),er[i]=(er[i-1]+er[i-1])%mo;
    for(int i=2;i<=n*2;i++) niy[i]=(niy[i]*niy[i-1])%mo;
    int x=n,y=n;niy[0]=1;
    while(x&&y)
    {
        int gu=read();
        cout<<c(x+y-2,x-1)*er[n+n+1-x-y]%mo<<"\n";
        if(gu==0) x--;else y--;
    }
}
View Code

t2 hongkong

暴力直接就可以过了。

正解是根据组合数公式一顿变形最后k+1个树状数组维护前缀和,每次查询把k扫一遍。

 

 t3

莫得了

posted @ 2020-02-03 22:43  精海臭脚  阅读(123)  评论(0编辑  收藏  举报