【BashuOJ1145】虚-组合数+求逆元
测试地址:虚
题目大意:在一个数轴上走,一开始在原点,每秒有
做法:这一套题,三道题我只会做第一道,好气啊!
(顺带一提,这三题题目拼音合起来是xu yi miao…你们这样都是要负责的)
这一题可以用组合数学中母函数的思想来想,不懂什么是母函数的同学可以去查。这里我们可以求
当然你也可以不用看上面这些废话,官方的题解是把每秒拆成两秒,每秒有
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 1000000007
using namespace std;
ll t,p,f[200010];
void exgcd(ll a,ll b,ll &x,ll &y)
{
ll x0=1,x1=0,y0=0,y1=1;
while(b)
{
ll q,tmp;
q=a/b;
tmp=x0-q*x1,x0=x1,x1=tmp;
tmp=y0-q*y1,y0=y1,y1=tmp;
tmp=a%b,a=b,b=tmp;
}
x=x0,y=y0;
}
ll inv(ll x)
{
ll a,b;
exgcd(x,mod,a,b);
return ((a%mod)+mod)%mod;
}
ll C(ll n,ll m)
{
if (m>n||m<0) return 0;
ll ans=f[n];
ans=(ans*inv(f[m]))%mod;
ans=(ans*inv(f[n-m]))%mod;
return ans;
}
ll power(ll a,ll b)
{
ll s=1,ss=a;
while(b)
{
if (b&1) s=(s*ss)%mod;
b>>=1;ss=(ss*ss)%mod;
}
return s;
}
int main()
{
scanf("%lld%lld",&t,&p);
f[0]=1;
for(ll i=1;i<=2*t;i++)
f[i]=(f[i-1]*i)%mod;
ll ans;
ans=C(2*t,p+t);
ans=(ans*inv(power(2,2*t)))%mod;
printf("%lld",ans);
return 0;
}