[BZOJ2982]combination

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
 

 
裸的卢卡斯, 第一次用心写纪念一下233
 

 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 10007
#define ll long long
inline int read(){
#define g getchar()
#define is isdigit(ch)    
    int res=0;char ch=g;
    while(!is) ch=g;
    while(is){res=(res<<3)+(res<<1)+(ch^48);ch=g;}
#undef d
#undef is
    return res;
}

int t, n, m;
int ksm(int x, int y)
{
    int res = 1;
    while(y)
    {
        if (y&1) res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return res;
}
int C(int n, int m)
{
    if (n < m) return 0;
    if (m > n - m) m = n - m;
    ll t1 = 1, t2 = 1;
    for (int i = 0 ; i < m ; i ++)
    {
        t1 = t1 * (n - i) % mod;
        t2 = t2 * (i + 1) % mod;
    }
    return t1 * ksm(t2, mod - 2) % mod;
}
int lucas(int n, int m)
{
    if (m == 0) return 1;
    return C(n % mod, m % mod) * lucas(n / mod, m / mod) % mod;
}

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

 

posted @ 2018-08-02 15:09  zZhBr  阅读(172)  评论(0编辑  收藏  举报