HDU 5407 CRB and Candies

题意:给一个正整数k,求lcm((k, 0), (k, 1), ..., (k, k))

解法:在oeis上查了这个序列,得知答案即为lcm(1, 2, ..., k + 1) / (k + 1),而分子有一个递推式,如果k为一个质数x的某次幂,那么ans[k]为ans[k - 1] * m,否则ans[k] = ans[k - 1]。做除法的时候用了逆元,因为取模来着。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
LL ans[1000005];
LL const mod = 1000000007;
bool isprime[1000005];
LL prime[1000005];
map <LL, int> m;
int cnt = 0;
void init()
{
    for(int i = 2; i < 1000005; i++)
    {
        if(!isprime[i])
        {
            prime[cnt++] = i;
            for(int j = i; j < 1000005; j += i)
                isprime[j] = 1;
        }
    }
    for(int i = 0; i < cnt; i++)
    {
        LL tmp = 1LL;
        while(tmp * prime[i] < 1000005)
        {
            tmp *= prime[i];
            m[tmp] = prime[i];
        }
    }
}
LL power(LL a, LL b, LL MOD) {
    LL res = 1;
    a %= MOD;
    while(b) {
        if(b & 1) {
            res = res * a % MOD;
            b--;
        }
        b >>= 1;
        a = a * a % MOD;
    }
    return res;
}
int main()
{
    init();
    ans[1] = 1;
    for(int i = 2; i < 1000005; i++)
    {
        if(m.count(i))
        {
            ans[i] = ans[i - 1] * m[i] % mod;
        }
        else
            ans[i] = ans[i - 1];
    }
    int T;
    while(~scanf("%d", &T))
    {
        int n;
        while(T--)
        {
            scanf("%d", &n);
            printf("%lld
", ans[n + 1] * power(n + 1, mod - 2, mod) % mod);
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Apro/p/4758359.html