Codeforces Round #818 (Div. 2) D. Madoka and The Corruption Scheme

 

Examples

input

1 1

output

2

input

2 1

output

3

input

3 2

output

7

Note

In the first example, there is only one match between players 11 and 22, so the sponsors can always make player 22 wins.

The tournament grid from the second example is shown in the picture in the statement.

题目大意:给我们两个数字n和k,表示现在有2^n个人进行比赛,两两比赛,赢的人进入下一轮,输的人淘汰,有两个人,第一个人想让最后赢的人的编号尽可能小,他可以率先决定第一轮比赛中比赛的双方,并且对于所有比赛他都可以决定谁获胜,然后第2个人想让最终获胜的人的编号尽可能大,他有k次机会可以逆转第一个人决定的输赢,也就是说在第一个人做好安排的基础上,第2个人可以选择k场比赛对比赛结果进行逆转,问我们最终获胜的人的最小的编号是多少。

解题思路:我们可以将整个比赛看成一个满二叉树,每次比赛赢的一方在右边,输的一方在左边。一个人要想获得最终的胜利,那么他就要赢得n场比赛,对于每一个标号,从上到下一条路径对应唯一的编号,我们设所有场次都赢的人的路径为RRRRR……RRRR(共n个R),现在开始分类讨论,如果k>=n,那么第2个人就可以扭转n场比赛从而让编号最大的人赢得这场比赛,如果k<n,那么第2个人最多让路径中出现k次L的人获得最终胜利,因为第一个人会采取最优策略,所以所以他会将标号从小到大依次将人安排到路径中L出现次数从少到多的位置上,路径中包含0个L的人数有C(n,0)个,包含1个L的人数有C(n,1)个,所以最终的答案就是C(n,0)+C(n,1)+……+C(n,k)。

上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int mod=1e9+7;
const int N=2e5+10;
int n,k;
long long fac[N],inv[N];
long long ksm(long long a,long long b)
{
	long long ans=1;
	while(b)
	{
		if(b&1)
		ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
long long c(int a,int b)
{
	long long ans=fac[a]*inv[b]%mod*inv[a-b]%mod;
	return ans;
}
int main()
{
	cin>>n>>k;
	k=min(k,n);
	fac[0]=1;
	fac[1]=1;
	for(int i=2;i<=n;i++)
	fac[i]=fac[i-1]*i%mod;
	inv[n]=ksm(fac[n],(long long)mod-2);
	for(int i=n-1;i>=0;i--)
	inv[i]=inv[i+1]*(i+1)%mod;
	long long res=0;
	for(int i=0;i<=k;i++)
	res=(res+c(n,i))%mod;
	cout<<res<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值