欧拉函数之和 51Nod - 1239
欧拉函数之和
预处理2/3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=5e6+5; 5 const int mod = 1000000007; 6 const int H_SZ = 131313; 7 ll phi[maxn], pri[maxn]; 8 struct HS{ 9 int head[H_SZ],nex[H_SZ]; 10 int cnt; 11 ll val[H_SZ],res[H_SZ]; 12 void init(){ 13 memset(head,-1,sizeof(head)); 14 cnt = 0; 15 } 16 void add(ll x, ll y) { 17 int u = x%H_SZ; 18 val[cnt] = x; 19 res[cnt] = y; 20 nex[cnt] = head[u]; 21 head[u] = cnt++; 22 } 23 ll query(ll x) { 24 int u = x%H_SZ; 25 for(int i = head[u]; ~i; i = nex[i]){ 26 if(val[i] == x) return res[i]; 27 } 28 return -H_SZ; 29 } 30 }hs; 31 void init(){ 32 phi[1] = 1; 33 int cnt = 0; 34 for(int i = 2; i < maxn; i++) { 35 if(!pri[i]) { 36 pri[cnt++] = i; 37 phi[i] = i-1; 38 } 39 for(int j = 0; j < cnt; j++) { 40 ll t = pri[j]*i; 41 if(t>=maxn) break; 42 pri[t] = 1; 43 if(i % pri[j] == 0) { 44 phi[t] = phi[i]*pri[j]; 45 break; 46 }else { 47 phi[t] = phi[i]*(pri[j]-1); 48 } 49 } 50 } 51 for(int i = 1; i < maxn;i++) phi[i] = (phi[i] + phi[i-1])%mod; 52 } 53 ll solve(ll a) { 54 ll res = a%mod*((a+1)%mod)/2; 55 ll r=2, l=2; 56 if(a < maxn) return phi[a]; 57 if(hs.query(a)!=-H_SZ) return hs.query(a); 58 while(l <= a){ 59 res -= solve(a/r)*(r-l+1); 60 res %= mod; 61 if(r == a) break; 62 l = r+1; 63 r = a/(a/l); 64 } 65 res = (res+mod)%mod; 66 hs.add(a, res); 67 return res; 68 } 69 70 int main() { 71 init(); 72 ll a; 73 while(scanf("%lld", &a)!=EOF) { 74 hs.init(); 75 printf("%lld\n", solve(a)); 76 } 77 }