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;
    }

  • 相关阅读:
    n皇后问题
    几种NFS系统对比,选型理由
    MooseFs集群故障恢复运维
    TB级NFS数据平滑迁移方案设计与实现
    NFS挂载各机显示用户不同的问题
    TB级NFS数据平滑迁移系列
    mysql备份和恢复
    Java基础赋值符号
    java 流程控制基础之if else
    Java基础赋值符号
  • 原文地址:https://www.cnblogs.com/dll6/p/7168722.html
Copyright © 2011-2022 走看看