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

  • 相关阅读:
    Struts2声明式异常处理
    几种常用的过滤器
    Jdk 和 Tomcat的 安装。(旧版本,请看新版本3篇)
    java 判断字符串是否相等
    PreparedStatement 查询 In 语句 setArray 等介绍。
    String、StringBuffer与StringBuilder之间区别
    IntelliJ IDEA 里 查看一个函数注释的方法是 ctrl+q
    Java字符串拼接效率对比
    Java 中判断字符串是否为空
    IntelliJ IDEA + Tomcat ;On Upate Action 与 On Frame Deactivation
  • 原文地址:https://www.cnblogs.com/dll6/p/7168722.html
Copyright © 2011-2022 走看看