1. 程式人生 > 實用技巧 >《51nod1237 最大公約數之和 V3》

《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