欧拉函数之和 51Nod

欧拉函数之和

 51Nod - 1239 

预处理2/3

 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
", solve(a));
76     }
77 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/7618386.html