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;
}
}
浙公网安备 33010602011771号