Codeforces Round #818 (Div. 2) D

博客讨论了一种有2n个选手的比赛场景,通过最优策略操作胜负二叉树序列确保1号选手始终获胜。作为赞助商,你可以修改k场比赛结果,目标是使最大编号的选手获胜。分析表明,k次操作能影响C(n, k)个选手,代码实现中计算了从0到k的组合数之和,以找出可能的最大获胜者数量。

D

题意

有2n 次方个选手,举办方通过最优策略操作胜负二叉树序列使得1选手始终赢得比赛,我们作为赞助商可以修改k场比赛的胜负,问我们能让最大编号的选手赢得比赛

分析

就着题目给出的二叉树模型,我们可以思考这样一个情景,一个叶子节点的选手要连续走n次左边才能赢得比赛,而现在我们只能修改k次,也就是说我们只能让最多k条边的右边选手赢得比赛,关键就是怎么表示这个选手的编号?
考虑k次操作能够让多少选手赢,那么能让选手赢的数量就是最大的编号数
k次操作能使k条右边变成左边,也就是有k条右边,n - k条左边的选手赢
这样的选手个数一共有C(n , k)个
所以我们只需要求C(n, 1~k)的和即可

代码实现

#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, mod = 1e9 + 7;
int n, k;
int qmi (int a, int b)
{
	int res = 1;
	
	while (b)
	{
		if (b & 1) res = res * a % mod;
		
		a = a * a % mod;
		b >>= 1;
	}
	
	return res;
}
signed main()
{
	ios::sync_with_stdio (0);
	cin.tie (0);
	cin >> n >> k;
	vector<int> fa (n + 1), infa (n + 1);
	fa[0] = 1;
	
	for (int i = 1; i <= n ; i ++)
		fa[i] = fa[i - 1] * i % mod;
		
	infa[n] = qmi (fa[n], mod - 2);
	
	for (int i = n ; i ; i --)
		infa[i - 1] = infa[i] * i % mod;
		
	int res = 0;
	
	for (int i = 0 ; i <= min (n, k); i ++)
		res = (res + (fa[n] * infa[i] % mod) * infa[n - i]) % mod;
		
	cout << res % mod << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值