51nod 1244 莫比乌斯函数之和

 

链接

 

题意

求a~b的莫比乌斯函数和,$a,b<=10^{10}$

 

分析

杜教筛+hash+记忆化

求$S(n) = \sum\limits_{i=1}^{n}μ(i)$


对于莫比乌斯函数有$\sum\limits_{d|i}μ(d)=[i=1]$


所以$S(n) = \sum\limits_{i=1}^{n}\sum\limits_{d|i}μ(d)-\sum\limits_{i=1}^{n}\sum\limits_{d|i,d≠i}μ(d)$


$=1-\sum\limits_{i=1}^{n}\sum\limits_{d|i,d≠1}μ(\lfloor\frac{i}{d}\rfloor)$


$=1-\sum\limits_{i=2}^{n}\sum\limits_{d=1}^{\lfloor\frac{n}{i}\rfloor}μ(d)$


$=1-\sum\limits_{i=2}^{n}S(\lfloor\frac{n}{i}\rfloor)$

 

code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 const int N = 5000000;
 7 const int mod = 1000007;
 8 typedef long long LL;
 9 
10 int prime[N+10],mu[N+10],tot,cnt;
11 bool noprime[N+10];
12 int h[mod],nxt[mod];
13 LL v[mod],d[mod];
14 
15 void getmu() {
16     mu[1] = 1;
17     for (int i=2; i<=N; ++i) {
18         if (!noprime[i]) prime[++tot] = i,mu[i] = -1;
19         for (int j=1; j<=tot&&i*prime[j]<=N; ++j) {
20             noprime[i*prime[j]] = true;
21             if (i % prime[j]==0) {mu[i*prime[j]] = 0;break;}
22             mu[i * prime[j]] = -mu[i];
23         }
24     }
25     for (int i=1; i<=N; ++i) mu[i] += mu[i-1];
26 }
27 void addhash(LL x,LL y) {
28     int p = x % mod;
29     d[++cnt] = x;v[cnt] = y;nxt[cnt] = h[p];h[p] = cnt;
30 }
31 int gethash(LL x) {
32     int p = h[x % mod];
33     while (p!=-1 && d[p]!=x) p=nxt[p];
34     return p;
35 }
36 LL Calc(LL x) {
37     if (x <= N) return (LL)mu[x];
38     int p = gethash(x);
39     if (p != -1) return v[p];
40     LL l=2,r,ret = 1;
41     while (l <= x) {
42         r = x / (x / l);
43         ret -= 1ll * (r - l + 1) * Calc(x / l);
44         l = r + 1;
45     }
46     addhash(x,ret);
47     return ret;
48 }
49 int main () {
50     memset(h,-1,sizeof(h));
51     memset(nxt,-1,sizeof(nxt));
52     LL a,b;
53     getmu();
54     cin >> a >> b;
55     cout << Calc(b) - Calc(a-1);
56     return 0;
57 }

 

posted @ 2018-02-08 08:27  MJT12044  阅读(169)  评论(0编辑  收藏  举报