zoukankan      html  css  js  c++  java
  • HDU5407.CRB and Candies(数论)

    官方题解:

    The problem is just to calculate g(N) = LCM(C(N,0),C(N,1),...,C(N,N))

    Introducing function f(n) = LCM(1,2,...,n), the fact g(n) = f(n+1)/(n+1) holds.

    We calculate f(n) in the following way.

    f(1)=1

    If n =p^k,then f(n) = f(n−1)× p, else f(n) = f(n−1).

    Time complexity:O(N⋅logN)

     

    这题用学的知识:

    1。乘法逆元

    求(a/b)%c时 化成 (a%c)/(b%c)是错误的,所以需要用到乘法逆元。(a%c)*(b^-1%c)。

    b^-1的求法:

    费马小定理(Fermat Theory): 假如p是质数,且Gcd(a,p)=1,那么 a^(p-1)(mod p)≡1。

    由此可得a*a^(p-2)=1 (mod p) 即a^(p-2)就是a的乘法逆元。通过快速幂可求。

    2。LCM(C(N,0),C(N,1),...,C(N,N))=LCM(1,2,...,n)/(n+1)

    知乎上看到有人证明,并没有看懂。http://www.zhihu.com/question/34859879

    3。求LCM(1,2,...,n)的简便算法

    If n =p^k,then f(n) = f(n−1)× p, else f(n) = f(n−1).

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    typedef long long ll;
    
    const int N = 1000002;
    const ll MOD = 1000000007;
    
    int v[N + 5];
    ll f[N + 5];
    int is_p[N + 5];
    int p[N + 5];
    int cnt_p;
    
    int n;
    
    void get_p()
    {
        for (int i = 0; i <= N; ++i) is_p[i] = 1;
        cnt_p = 0;
        is_p[0] = is_p[1] = 0;
        for (int i = 2; i <= N; ++i) {
            if (is_p[i]) {
                p[cnt_p++] = i;
                for (int j = i * 2; j <= N; j += i)
                    is_p[j] = 0;
            }
        }
    }
    
    ll pow(ll a, ll b)
    {
        ll res = 1;
        while (b > 0) {
            if (b & 1) res = res * a % MOD;
            a = a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    
    ll MIM(ll a)
    {
        return pow(a, MOD-2);
    }
    
    void get_f()
    {
        for (int i = 0; i < cnt_p; ++i) {
            ll j = 1;
            while (j < N) {
                v[j] = p[i];
                j *= p[i];
            }
        }
        f[1] = 1;
        for (int i = 2; i <= N; ++i) {
            if (v[i]) f[i] = f[i - 1] * v[i] % MOD;
            else f[i] = f[i - 1];
        }
    }
    
    int main()
    {
        get_p();
        get_f();
    
        int t;
        scanf("%d", &t);
        while (t--) {
            scanf("%d", &n);
            
            printf("%lld
    ", f[n + 1] * MIM(n + 1) % MOD);
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    学好VC++的十大良好习惯
    VC6.0调试技巧
    匈牙利命名法
    VC中常用文件操作(三)
    VL_FEAT——图像处理函数库
    MATLAB——linspace
    (Your)((Term)((Project)))(字符串处理)
    Matrix Chain Multiplication(栈的简单应用)
    The Triangle(DP基础)
    MATLAB——polyfit
  • 原文地址:https://www.cnblogs.com/wenruo/p/4750176.html
Copyright © 2011-2022 走看看