zoukankan      html  css  js  c++  java
  • light oj 1067 费马小定理求逆元

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1067

    1067 - Combinations

    Given n different objects, you want to take k of them. How many ways to can do it?

    For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways.

    Take 1, 2

    Take 1, 3

    Take 1, 4

    Take 2, 3

    Take 2, 4

    Take 3, 4

    Input

    Input starts with an integer T (≤ 2000), denoting the number of test cases.

    Each test case contains two integers n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).

    Output

    For each case, output the case number and the desired value. Since the result can be very large, you have to print the result modulo 1000003.

    Sample Input

    Output for Sample Input

    3

    4 2

    5 0

    6 4

    Case 1: 6

    Case 2: 1

    Case 3: 15

    分析:

    时间只有2秒,T组测试数据加上n的106达到了109递推肯定超时,那么考虑组合公式,C(n,k)=n!/(k!*(n-k)!);先打一个阶乘的表(当然要取模,只有106),然后就是这个除法取模的问题,当然是求逆元,(a/b)%mod=a*(b对mod 的逆元);求逆元可以用扩欧和费马小定理。

    费马小定理的使用条件mod必须为素数。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<stack>
    using namespace std;
    #define N 1000009
    #define mod 1000003
    #define LL long long

    LL fact[N];

    void init()
    {
    fact[0] = fact[1] = 1;

    for(int i = 2; i < N; i++)
    fact[i] = (fact[i-1] * i) % mod;
    }
    /*LL niyuan(int a, int p)
    {
    LL ans = 1;

    if(p == 0)
    return 1;

    while(p)
    {
    if(p & 1)
    ans = (ans * a) % mod;
    a = (a * a) % mod;
    p >>= 1;
    }
    return ans;

    }*/

    LL niyuan(int a, int b)///就是一个快速幂。
    {
    if(b == 0)
    return 1;

    LL x = niyuan(a, b / 2);

    LL ans = x * x % mod;

    if(b % 2 == 1)
    ans = ans * a % mod;

    return ans;
    }
    LL c(int n, int k)
    {
    LL fm = (fact[k] * fact[n-k]) % mod;///n! * (n-m)!.
    LL ans1 = niyuan(fm, mod - 2);///求n!的逆元。

    return (ans1 * fact[n]) % mod;///公式(a / b ) % mod = (a * a ^(mod-2) % mod。
    }
    int main(void)
    {
    int T, cas;
    int n, k;

    init();
    scanf("%d", &T);
    cas = 0;

    while(T--)
    {
    cas++;
    scanf("%d%d", &n, &k);
    if(2 * k > n)///组合数性质。
    k = n - k;

    printf("Case %d: %lld ", cas, c(n, k));

    }
    return 0;
    }

  • 相关阅读:
    何谓算法
    大规模Web服务开发技术
    什么是依赖,什么是抽象
    智能Web算法
    算法评测
    好代码、坏代码之四
    SVN server setup 1
    Python正则表达式操作指南(re使用)(转)
    rpm package installation
    mysql install error:Make had returned bad status, install seems impossible
  • 原文地址:https://www.cnblogs.com/dll6/p/7168722.html
Copyright © 2011-2022 走看看