《51nod1237 最大公约数之和 V3》

好题:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define dbg(x) cout << "now this num is " << x << endl;
inline LL read()
{
    LL x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
    return x * f;
}
int prime[N],tot = 0;
LL phi[N],inv2 = 500000004;
bool vis[N];
unordered_map<LL,LL> mp;
inline void init()
{
    phi[1] = 1;
    for(int i = 2;i < N;++i)
    {
        if(!vis[i])
        {
            prime[++tot] = i;
            phi[i] = i - 1;
        }
        for(int j = 1;j <= tot && prime[j] * i < N;++j)
        {
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0){phi[i * prime[j]] = phi[i] * prime[j];break;}
            else phi[i * prime[j]] = phi[i] * phi[prime[j]];
        }
    }
    for(int i = 1;i < N;++i) phi[i] = (phi[i] + phi[i - 1]) % Mod;
}
LL solve(LL n)
{
    if(n < N) return phi[n];
    if(mp[n]) return mp[n];
    LL ans = 0;
    for(LL L = 2,r = 0;L <= n;L = r + 1)
    {
        r = n / (n / L);
        ans = (ans + (r - L + 1) % Mod * solve(n / L) % Mod) % Mod;
    }
    ans = (((1 + n)%Mod * (n%Mod) % Mod * inv2 % Mod - ans) % Mod + Mod) % Mod;
    return mp[n] = ans;
}
int main()
{
    init();
    LL n;n = read();
    LL ans = 0;
    for(LL L = 1,r = 0;L <= n;L = r + 1)
    {
        r = n / (n / L);
        LL ma = ((solve(r) - solve(L - 1)) % Mod + Mod) % Mod;
        LL f = (n / L) % Mod;
        ans = (ans + ma * f % Mod * f % Mod) % Mod;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2020-11-01 14:39  levill  阅读(101)  评论(0编辑  收藏  举报