bzoj 2982: combination (Lucas定理)

来源:互联网 发布:淘宝申请账号注册 编辑:程序博客网 时间:2024/05/21 09:09

2982: combination

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 465  Solved: 288
[Submit][Status][Discuss]

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

HINT

Source

[Submit][Status][Discuss]


题解:Lucas定理

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define p 10007using namespace std;int jc[p+100],n,m;void init(){jc[0]=jc[1]=1;for (int i=2;i<=p;i++) jc[i]=jc[i-1]*i%p;}int quickpow(int num,int x){int base=num%p; int ans=1;while (x) {if (x&1) ans=ans*base%p;x>>=1;base=base*base%p;}return ans;}int calc(int n,int m){if (m>n) return 0;return jc[n]*quickpow(jc[m]*jc[n-m]%p,p-2)%p;}int lucas(int n,int m){if (!m) return 1;return calc(n%p,m%p)*lucas(n/p,m/p)%p;}int main(){freopen("a.in","r",stdin);init();int T; scanf("%d",&T);while (T--) {scanf("%d%d",&n,&m);printf("%d\n",lucas(n,m)%p);}}



0 0