其他分享
首页 > 其他分享> > Codeforces Round #818 (Div. 2) D

Codeforces Round #818 (Div. 2) D

作者:互联网

 

 

D:

题意: 由2^n个人进行锦标赛,编号1~2^n,每一场输的人失去比赛资格,赢的人继续。你可以选择他们进行的顺序,以及决定哪一边赢得比赛。你的目标是尽量让编号小的人赢得最终比赛。主办方可以改变其中至多k场比赛的结果,即本来是左边赢改为右边赢,本来是右边赢的改为左边。如下图,最左边红线是你选择的胜方。而主办方改动左边的一个结果,使得最终赢的人变成3。 问题是,求一个最小的编号,使得主办方无论怎么改,都可以让他赢。主办方的目的是使编号尽可能大的人赢。

分析:

 

杨辉三角最后一排的和刚好是2^n,也就是最后一排刚好有2^n 个人,杨辉三角,从左往右数,每个位置i ,代表这个位置经过 i 次修改后可以获胜,且这个数的右上角的数是上一层经过 i 次修改可以获胜的数,所以这一层的这一个数在杨辉三角中也代表经过刚好 i 次修改,整个杨辉三角中可以获胜的数的总和。

首先让最左边的人赢,我们让编号小的人尽量在左边,这样如果主办方仅修改一次,左边一侧的1的右边一个会刚好获胜,修改两次,右边第二个刚好会获胜,所以修改k次后会获得胜利的数直接通过累加最后一排的k个数即可

 

 答案就是 s

//#define int ll
const int N = 2e5+10,mod = 1e9+7;
int n,k;

int fac[N],inv[N];

ll qmi(ll a,ll b) {
    ll res = 1;for(;b;b>>=1,a = a * a % mod) if(b&1) res = res * a % mod;return res;
}

ll mul(ll a,ll b) {
    return (a * b) % mod;
}

void init() {
    fac[0] = 1;
    fo(i,1,2e5) fac[i] = (1ll * fac[i-1] * i) % mod;//记得要开ll
    inv[200000] = qmi(fac[200000],mod - 2);
    of(i,2e5,1) inv[i-1] = mul(inv[i],i);
}

ll C(ll n,ll m) {
    if(n < m || m < 0) return 0;
    return mul(fac[n],mul(inv[m],inv[n-m]));
}

void solve()
{
    cin>>n>>k;
    ll res = 0;
//    fo(i,0,10) {
//        dbb(i,fac[i]);
//    }
//    db(C(1,1));
    fo(i,0,(min(k,n))) 
    {
        
        res += C(n,i);
        res %= mod;
    } 
    cout<<res<<endl;
}

 

 

标签:res,ll,Codeforces,818,左边,fac,Div,inv,mod
来源: https://www.cnblogs.com/er007/p/16653787.html