hdu6134[莫比乌斯反演] 2017多校8

 

/*hdu6134[莫比乌斯反演] 2017多校8*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 1000000007;
const int maxn = 1000000 + 5;
LL f[maxn], g[maxn], d[maxn];
bool vis[maxn];
int prime[maxn], primes, mu[maxn];
void init_mu()
{
    memset(vis, 0, sizeof(vis));
    mu[1] = 1;
    primes = 0;
    for (int i = 2; i < maxn; i++)
    {
        if (!vis[i]) {
            prime[primes++] = i;
            mu[i] = -1;
        }
        for (int j = 0; j < primes && i * prime[j] < maxn; j++)
        {
            vis[i * prime[j]] = 1;
            if (i % prime[j]) mu[i * prime[j]] = -mu[i];
            else { mu[i * prime[j]] = 0; break;}
        }
    }
}
void init() {
    init_mu();
    for (int i = 1; i < maxn; i++) {
        for (int j = i; j < maxn; j += i) {
            d[j]++;
            if (d[j] > MOD) d[j] -= MOD;
        }
    }
    g[1] = 1;
    for (int i = 2; i < maxn; i++) {
        g[i] = (g[i - 1] + d[i - 1] + 1) % MOD;
    }
    for (int i = 1; i < maxn; i++) {
        for (int j = i; j < maxn; j += i) {
            f[j] = (f[j] + mu[i] * g[j / i] % MOD) % MOD;
        }
    }
    for (int i = 1; i < maxn; i++) {
        f[i] = (f[i - 1] + f[i]) % MOD;
    }
}
int main() {
    init();
    int n;
    while (~scanf("%d", &n)) {
        printf("%lld\n", f[n]);
    }
    return 0;
}

 

posted @ 2017-08-18 03:09  UnderSilence  阅读(201)  评论(0编辑  收藏  举报