首页 > 其他分享 >cf1717D

cf1717D

时间:2023-05-25 13:34:15浏览次数:31  
标签:mo int ll ans include inv cf1717D

D. Madoka and The Corruption Scheme
一道有点意思的题目。
首先对于Madoka给出的任意一颗二叉树,我们可以将其进行调整。使得对于一个节点左边的总是获胜。也就是对于对于每一个子树,左边的最小值小于右边的最小值。
那么要将一个点作为最后的冠军,只需满足它到根,经过的右儿子不超过k即可。
那么只需将1,2,3......依次填到经过右儿子数量为0,经过右儿子的边数量为1的点,这样填肯定是最好的。
那么怎么计数呢,
记f[i]表示从叶子到根经过多少个右儿子。
n=1时 f[0]=1 f[1]=1

n=2时 f[0]=1
f[1]=f[1] (左) +f[0] (右)
f[2]=f[1] (右)
可以发现就是杨辉三角
\(ans=\sum_{i=1}^{min(n,k)}C_{n}^{i}\)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define A puts("Yes") 
#define B puts("No")
using namespace std;
typedef long long ll;
const int N=2e5+5;
const ll mo=1e9+7;

ll inv[N],f[N],ans;
int n,k;
ll power(ll a,ll b){
	ll t=1,y=a%mo;
	while (b){
		if (b&1) t=t*y%mo;
		y=y*y%mo;
		b/=2;
	}
	return t;
}
ll C(int n,int m){
	return f[n]*inv[m]%mo*inv[n-m]%mo;
	
}
int main(){
	
//	freopen("data.in","r",stdin);		
	scanf("%d %d",&n,&k);
	k=min(n,k);
	
	f[0]=1;
	fo(i,1,n) f[i]=f[i-1]*(ll)i%mo;
	
	inv[n]=power(f[n],mo-2);
	fd(i,n-1,0) inv[i]=inv[i+1]*(ll)(i+1)%mo;

	fo(i,0,k) ans=(ans+C(n,i))%mo;
	printf("%lld\n",ans);
	return 0;
}
  



 

标签:mo,int,ll,ans,include,inv,cf1717D
From: https://www.cnblogs.com/ganking/p/17430900.html

相关文章

  • CF1717D Madoka and The Corruption Scheme
    首先注意到我们同一层不可能会修改多次比赛结果,因为Sponsors一定会定准一个目标然后修改结果,据此\(k>n\)可以视作\(k=n\)。因此某个叶子如果被选为冠军,那么根节点到......