Bzoj2982 combination

Posted by yjjr's blog on February 6, 2018

标签:Lucas定理,数学,逆元

Description

LMZn个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样。那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值。(1<=m<=n<=200,000,000)

Input

 第一行一个整数t,表示有t组数据。(t<=200)

 接下来t行每行两个整数n, m,如题意。

Output

T行,每行一个数,为C(n,m) mod 10007的答案。

Sample Input

4

5 1

5 2

7 3

4 2

Sample Output

5

10

35

6

 

分析:C(n,m)直接套用lucas定理和逆元的裸题

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define mem(x,num) memset(x,num,sizeof x)
#define LL long long
using namespace std;
inline LL read()
{
	LL f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int p=10007;
int fac[p],inv[p],n,m,T;
void work()
{
	fac[0]=fac[1]=inv[0]=inv[1]=1;
	rep(i,2,p-1)fac[i]=fac[i-1]*i%p;
	rep(i,2,p-1)inv[i]=(p-p/i)*inv[p%i]%p;
	rep(i,1,p-1)inv[i]=inv[i-1]*inv[i]%p;
}

int C(int n,int m)
{
	if(n<m)return 0;
	if(n<p&&m<p)return fac[n]*inv[m]%p*inv[n-m]%p;
	return C(n/p,m/p)*C(n%p,m%p)%p;
}

int main()
{
	work();
	T=read();
	while(T--)
	{
		n=read(),m=read();
		printf("%d\n",C(n,m));
	}
	return 0;
}


本文可以转载,但必须附上原文链接,否则你会终生找不到妹子!!!欢迎关注我的CSDN: ahyjjr