AtCoder Beginner Contest 205 E - White and Black Balls(卡特兰数变形)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 205 E - White and Black Balls(卡特兰数变形)相关的知识,希望对你有一定的参考价值。
看到题目非常像卡特兰数,实际上就是
考虑以 ( 0 , 0 ) (0,0) (0,0)为起点,选白球相当于往右下走一步,黑球相当于向右上走一步
白球 n n n个,黑球 m m m个,设 x = m − n x=m-n x=m−n(先设 m > = n m>=n m>=n)
放在坐标轴上,类似这样的一张图
不管怎么走,最后终点都是 ( n + m , x ) (n+m,x) (n+m,x)
总的方案是 ( n + m n ) \\binom{n+m}{n} (nn+m),我们需要知道不合法的方案是多少
容易看出,只要上面的折线越过了 y = − k y=-k y=−k这根直线就不合法
我们构造另一条折现,以 y = − k − 1 y=-k-1 y=−k−1为对称轴翻转得到
发现翻转后折线的终点变为 ( n + m , 2 k + 2 + x ) (n+m,2k+2+x) (n+m,2k+2+x)
也就是不合法的方案数相当于向下走 z z z步,满足 z − ( n + m − z ) = 2 k + 2 + x z-(n+m-z)=2k+2+x z−(n+m−z)=2k+2+x
于是真正的方案数为 ( n + m n ) − ( n + m z ) \\binom{n+m}{n}-\\binom{n+m}{z} (nn+m)−(zn+m)
当 n < m n<m n<m时同理
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9+7;
const int maxn = 2e6+10;
int n,m,k,fac[maxn];
int quick(int x,int n)
{
int ans = 1;
for( ; n ; n>>=1,x=x*x%mod )
if( n&1 ) ans = ans*x%mod;
return ans;
}
int C(int n,int m)
{
if( n<m ) return 0ll;
return fac[n]*quick( fac[m]*fac[n-m]%mod,mod-2 )%mod;
}
signed main()
{
fac[0] = 1;
for(int i=1;i<=2000000;i++) fac[i] = fac[i-1]*i%mod;
cin >> n >> m >> k;
if( m+k<n ) puts("0");
else
{
//满足m+k>=n
int ans = 0;
if( m>=n )
{
int x = m-n;
int z = (2*k+2+x+n+m)/2;
ans = C(n+m,m)-C(n+m,z);
}
else
{
int x = n-m;
int z = (2*k+2-x+n+m)/2;
ans = C(n+m,m)-C(n+m,z);
}
cout << ( ans%mod+mod )%mod;
}
}
以上是关于AtCoder Beginner Contest 205 E - White and Black Balls(卡特兰数变形)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解