# 数论

①式的一个变形。

 1 #include <cstdio>
2 #include <algorithm>
3 #include <cmath>
4 #include <cstring>
5
6 typedef long long LL;
7 const int N = 4900010;
8 const LL INF = 0x7f7f7f7f7f7f7f7fll;
9
10 int p[N], top, miu[N], T;
11 LL Miu[N], n, miU[N];
12 bool vis[N];
13
14 inline void getp(int n) {
15     miu[1] = 1;
16     for(int i = 2; i <= n; i++) {
17         if(!vis[i]) {
18             p[++top] = i;
19             miu[i] = -1;
20         }
21         for(int j = 1; j <= top && i * p[j] <= n; j++) {
22             vis[i * p[j]] = 1;
23             if(i % p[j] == 0) {
24                 break;
25             }
26             miu[i * p[j]] = -miu[i]; /// get miu phi when visit
27         }
28     }
29     for(int i = 1; i <= n; i++) {
30         Miu[i] = Miu[i - 1] + miu[i];
31     }
32     return;
33 }
34
35 LL solve(LL x) {
36     //printf("T = %d \n", T);
37     if(x <= 0) return 0;
38     if(x <= T) return Miu[x];
39     if(miU[n / x] != INF) return miU[n / x];
40     //printf("x = %lld T = %d \n", x, T);
41     LL ans = 1;
42     for(LL i = 2, j; i <= x; i = j + 1) {
43         j = x / (x / i); // [i, j]
44         ans -= (j - i + 1) * solve(x / i);
45     }
46     return miU[n / x] = ans;
47 }
48
49 LL work(LL x) {
50     n = x;
51     memset(miU, 0x7f, sizeof(miU));
52     return solve(x);
53 }
54
55 int main() {
56     LL l, r;
57     scanf("%lld%lld", &l, &r);
58     T = (int)pow(r, 2.0/3.0);
59
60     getp(T);
61     printf("%lld\n", work(r) - work(l - 1));
62
63     return 0;
64 }
51nod1244 莫比乌斯函数之和
 1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4
5 typedef long long LL;
6 const LL MO = 1000000007;
7 const int N = 5000010;
8
9 int T, p[N], top, phi[N];
10 bool vis[N];
11 LL n, Phi[N], phI[N], inv2;
12
13 inline void getp(int n) {
14     phi[1] = 1;
15     for(int i = 2; i <= n; i++) {
16         if(!vis[i]) {
17             p[++top] = i;
18             phi[i] = i - 1;
19         }
20         for(int j = 1; j <= top && i * p[j] <= n; j++) {
21             vis[i * p[j]] = 1;
22             if(i % p[j] == 0) {
23                 phi[i * p[j]] = phi[i] * p[j] % MO;
24                 break;
25             }
26             phi[i * p[j]] = phi[i] * (p[j] - 1) % MO;
27         }
28     }
29     for(int i = 1; i <= n; i++) {
30         Phi[i] = (Phi[i - 1] + phi[i]) % MO;
31     }
32     return;
33 }
34
35 LL solve(LL x) {
36     if(x <= 0) return 0;
37     if(x <= T) return Phi[x];
38     if(phI[n / x] != -1) return phI[n / x];
39     LL ans = (x + 1) % MO * (x % MO) % MO * inv2 % MO;
40     for(LL i = 2, j; i <= x; i = j + 1) {
41         j = x / (x / i);
42         ans -= (j - i + 1) % MO * solve(x / i) % MO;
43         ans = (ans % MO + MO) % MO;
44     }
45     return phI[n / x] = ans;
46 }
47
48 inline LL work(LL x) {
49     n = x;
50     memset(phI, -1, sizeof(phI));
51     return solve(x);
52 }
53
54 int main() {
55     inv2 = (MO + 1) / 2;
56     LL x;
57     scanf("%lld", &x);
58     T = pow(x, 2.0 / 3);
59     getp(T);
60     printf("%lld\n", work(x));
61     return 0;
62 }
51nod1239 欧拉函数之和
 1 #include <cstdio>
2 #include <cmath>
3 #include <tr1/unordered_map>
4
5 typedef long long LL;
6 const int N = 1000010, T = 1000000;
7
8 std::tr1::unordered_map<LL, LL> phI;
9 std::tr1::unordered_map<LL, int> miU;
10 int p[N], top, phi[N], miu[N], Miu[N], n;
11 LL Phi[N];
12 bool vis[N];
13
14 inline void getp(int n) {
15     phi[1] = miu[1] = 1;
16     for(int i = 2; i <= n; i++) {
17         if(!vis[i]) {
18             p[++top] = i;
19             miu[i] = -1;
20             phi[i] = i - 1;
21         }
22         for(int j = 1; j <= top && i * p[j] <= n; j++) {
23             vis[i * p[j]] = 1;
24             if(i % p[j] == 0) {
25                 phi[i * p[j]] = phi[i] * p[j];
26                 break;
27             }
28             phi[i * p[j]] = phi[i] * (p[j] - 1);
29             miu[i * p[j]] = -miu[i];
30         }
31     }
32     for(int i = 1; i <= n; i++) {
33         Phi[i] = Phi[i - 1] + phi[i];
34         Miu[i] = Miu[i - 1] + miu[i];
35     }
36     return;
37 }
38
39 LL getPhi(int x) {
40     if(x <= 0) return 0;
41     if(x <= T) return Phi[x];
42     if(phI.count(x)) return phI[x];
43     LL ans = x * (x + 1ll) / 2;
44     for(unsigned i = 2, j; i <= x; i = j + 1) {
45         j = x / (x / i);
46         ans -= (j - i + 1) * getPhi(x / i);
47     }
48     return phI[x] = ans;
49 }
50
51 int getMiu(int x) {
52     if(x <= 0) return 0;
53     if(x <= T) return Miu[x];
54     if(miU.count(x)) return miU[x];
55     int ans = 1;
56     for(unsigned i = 2, j; i <= x; i = j + 1) {
57         j = x / (x / i);
58         ans -= (j - i + 1) * getMiu(x / i);
59     }
60     return miU[x] = ans;
61 }
62
63 int main() {
64     getp(T);
65     int q;
66     scanf("%d", &q);
67     for(int i = 1; i <= q; i++) {
68         scanf("%d", &n);
69         printf("%lld %d\n", getPhi(n), getMiu(n));
70     }
71
72     return 0;
73 }
BZOJ3944 Sum

f(x) = x2 的前缀和: F(x) = x(x + 1)(2x + 1) / 6

f(x) = x3 的前缀和: F(x) = (1+2+3+...+x)2

posted @ 2019-02-26 11:06  huyufeifei  阅读(...)  评论(...编辑  收藏