1. 程式人生 > >歐拉函數之和 51Nod - 1239

歐拉函數之和 51Nod - 1239

pre col color tar its res ide lan display

歐拉函數之和

51Nod - 1239

技術分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn=5e6+5;
 5 const int mod = 1234567;
 6 const int MOD = 1000000007;
 7 ll phi[maxn], pri[maxn];
 8 struct HS{
 9     int head[mod],nex[mod];
10     int cnt;
11     ll val[mod],ref[mod];
12 void init(){ 13 memset(head,-1,sizeof(head)); 14 cnt = 0; 15 } 16 void add(ll x, ll y) { 17 int u = x%mod; 18 val[cnt] = x; 19 ref[cnt] = y; 20 nex[cnt] = head[u]; 21 head[u] = cnt++; 22 } 23 ll query(ll x) { 24 int
u = x%mod; 25 for(int i = head[u]; ~i; i = nex[i]){ 26 if(val[i] == x) return ref[i]; 27 } 28 return -mod; 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)!=-mod) 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 hs.add(a,(res+MOD)%MOD); 66 return (res+MOD)%MOD; 67 } 68 69 int main() { 70 init(); 71 ll a; 72 while(scanf("%lld",&a)!=EOF) { 73 hs.init(); 74 printf("%lld\n", solve(a)); 75 } 76 }
View Code

。。。。。。。。。。。。。每天再搞。。。。。。。。

歐拉函數之和 51Nod - 1239