最后求教我们的大牛:神奇的ben1222。他帮我看了很久最后发现我的a^b % c的运算中有溢出,但是不化简的式子华丽的没被测试数据发现。然后...
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const long md = 20100501;
/**
* a的b次方Mod c
* 参数为整数
* 使用时注意修改类型
*/
long PowerMod(long long a,long b,long c)
{
long long tmpInt = 1;
while (b > 0)
{
if (b & 1)
tmpInt = (tmpInt * a) % c;
a = (a * a) % c;
b >>= 1;
}
return tmpInt;
}
/**
* 线性筛法求素数表
* 复杂度: O(n)
*/
const long MAXP = 2000005;
long prime[MAXP] = {0},num_prime = 0;
int isNotPrime[MAXP] = {1, 1};
void GetPrime_Init()//初始化调用
{
long i, j;
for(i = 2 ; i < MAXP ; i ++)
{
if(! isNotPrime[i])
prime[num_prime ++] = i;
for(j = 0 ; j < num_prime && i * prime[j] < MAXP ; j ++)
{
isNotPrime[i * prime[j]] = 1;
if( !(i % prime[j]))
break;
}
}
}
/**
* 排列组合数(素数表示法)
*/
// 全排列
// 参数: A(n), *p 传出数的数组表示指针
// 返回值:结果包含的素数个数
long Arrangement(long n, long p[])
{
long t, i;
for(i = 0; i < num_prime && prime[i] <= n; i ++)
{
t = n;
while(t)
*(p + i) += t / prime[i], t /= prime[i];
}
return i;
}
long numRec[3][MAXP / 10];
//long numRec[MAXP / 10];
int main()
{
long t,n,m,r,i;
long tmp;
long long res;
GetPrime_Init();
scanf("%ld", &t);
while(t --)
{
cin>> n>> m;
res = 1;
memset(numRec, 0, sizeof(numRec));
r = Arrangement(m + n, numRec[0]);
Arrangement(n + 1, numRec[1]);
Arrangement(m, numRec[2]);
//res = (((m + n)! * (n + 1 - m)) / ((n + 1)! * m!)) % md;
tmp = n + 1 - m;
for(i = 0; tmp > 1 && i < num_prime && prime[i] <= tmp; i ++)
while(tmp > 1 && tmp % prime[i] == 0)
numRec[0][i] ++, tmp /= prime[i];
for(i = 0; i <= r; i ++)
res = (res * PowerMod(prime[i], numRec[0][i] - numRec[1][i] - numRec[2][i], md)) % md;
printf("%lld\n", res);
}
return 0;
}