链接:https://ac.nowcoder.com/acm/contest/4381/B
题目描述
牛牛并不是一个擅长组合数学的选手,但是这并不妨碍他喜欢做组合数学。虽然他人是菜,但是他嘴巴不菜。
众所周知,计算组合数C_i^jCij是组合数学中最简单的事情.现在牛牛遇到了一个难题,给出n,m,pn,m,p,他想知道C_n^mCnm是否等于pp。
输入描述:
一行三个数分别代表n,m,pn,m,p.
输出描述:
如果C_n^m = pCnm=p,输出Yes!Yes!.否则输出No!No!
示例1
输入
复制
4 2 6
输出
复制
Yes!
备注:
1 \leq n \leq 1e91≤n≤1e9
0 \leq m \leq \min(1e5, n)0≤m≤min(1e5,n)
1 \leq p \leq 10^{4e5}1≤p≤104e5
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int quick_power_mod(int a,int b,int m)
{
int result = 1;
int base = a;
while(b>0)
{
if(b&1==1)
result=(result*base)%m;
base=(base*base)%m;
b>>=1;
}
return result;
}
ll comp(ll a,ll b,int p)
{
if(a<b)return 0;
if(a==b)return 1;
if(b>a-b)b=a-b;
int ans=1,ca=1,cb=1;
for(ll i=0;i<b;i++)
{
ca=(ca*(a-i))%p;
cb=(cb*(b-i))%p;
}
ans=(ca*quick_power_mod(cb,p-2,p))%p;
return ans;
}
ll lucas(ll n,ll m,ll p)
{
ll ans=1;
while(n&&m&&ans)
{
ans=(ans*comp(n%p,m%p,p))%p;
n/=p;
m/=p;
}
return ans;
}
char str[1000001];
int main()
{
ll m,n;
scanf("%lld %lld %s",&n,&m,str);
ll ans=0,s;
s=strlen(str);
ll mod=10007;
for(int i=0;i<s;i++)
{
ans=ans*10+str[i]-'0';
ans%=mod;
}
if(lucas(n,m,10007)==ans)
cout<<"Yes!"<<endl;
else
cout<<"No!"<<endl;
return 0;
}