hdu 3037 Saving Beans ——lucas定理

昨天用的那个模版搞不了这个题……只能随用随算了

预处理还是每一次都把阶乘和逆求出来

这次求逆用的是欧拉定理,査了信数书才发现的,原来求逆可以不用欧几里德呀!

这次尝试用了一下TC模版,挺有意思的……以后就这么上好了

还有就是乘法的时候注意要强制类型转换,否则会溢出

2011-08-21 10:18:28 Accepted 3037 1250MS 708K 1437 B G++ Tiramitu

#include <cstdio>
#include
<cstring>
#include
<cstdlib>
#include
<cctype>
#include
<cmath>
#include
<time.h>
#include
<set>
#include
<map>
#include
<stack>
#include
<queue>
#include
<string>
#include
<bitset>
#include
<vector>
#include
<deque>
#include
<list>
#include
<sstream>
#include
<iostream>
#include
<functional>
#include
<numeric>
#include
<algorithm>
#define eps 1e-9
#define CLR(arr,v) memset(arr,v,sizeof(arr));
#define FOR(i,s,e) for((i)=(s);(i)<=(e);i++)
#define sq(x) ((a)*(a))
#define LL long long
#define DB double
#define LDB long double
#define pb push_back
#define MAXN 100000+10
#define PRIME 8700

using namespace std;

int mod;
int pmod[MAXN];//保存阶乘模

void init()
{
int i;
pmod[
0]=1;
FOR(i,
1,mod)
{
pmod[i]
=(LL)pmod[i-1]*i%mod;
}
}

int quickmod(int a,int b)
{
if(b==0)
return 1;
if(b==1)
return a;
LL ans
=quickmod(a,b/2);
ans
=(LL)ans*(LL)ans%mod;
if(b%2==1)
ans
=(LL)ans*a%mod;
return ans%mod;
}

int c(int n,int m)
{
if(m>n)
return 0;
int res=1;
int a=(LL)pmod[n-m]*pmod[m]%mod;
int b=mod-2;
res
=(LL)pmod[n]*quickmod(a,b)%mod;
return res;
}

int lucas(int n,int m)
{
int ans=1;
while(n&&m)
{
ans
=(LL)ans*c(n%mod,m%mod)%mod;
n
/=mod;
m
/=mod;
}
return ans;
}

int main(void)
{
int T;
cin
>>T;
LL n,m;
while(T--)
{
cin
>>n>>m>>mod;
init();
cout
<<lucas(n+m,n)<<endl;
}
}

你可能感兴趣的:(bean)