Mertens

Posted ph = x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mertens相关的知识,希望对你有一定的参考价值。

题意:

求解$\\sum_{i=a}^b{\\mu(i)}$。

 

解法:

由$(\\mu * I)(n) = e(n)$ 得 $\\sum_{d|n}{\\mu(d)} = [n=1]$ 得 $\\mu(n) = \\sum_{d|n,d<n}{\\mu(d)}$

从而有$$\\sum_{i=1}^n{\\mu(i)} = 1 - \\sum_{i=1}^n{ \\sum_{d|i,d<i}{\\mu(d)} }$$

    $$=1-\\sum_{t=2}^n{ \\sum_{d=1}^{[\\frac{n}{t}]}{\\mu(d)} }$$

记$S(n) = \\sum_{i=1}^n{\\mu(i)}$

从而有$S(n) = 1- \\sum_{t=2}^n{S([\\frac{n}{t}])}$

考虑分块优化此式,产生$O(\\sqrt n)$的时间复杂度,当n小于等于$n^{0.6667}$时直接应用线性筛计算。

分析得会产生$O(n^{0.667})$个n,从而应用map,递归计算即可。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring> 
 4 #include <ctime>
 5 #include <map>
 6 
 7 #define LL long long
 8 #define LIM 5000000
 9 
10 using namespace std;
11 
12 int tot,prime[LIM+10];
13 LL u[LIM+10];
14 bool v[LIM+10];
15 map<LL,LL> ansv;
16 
17 LL S(LL n)
18 {
19     if(n<=LIM) return u[n];
20     if(ansv.count(n)) return ansv[n];
21     LL j;
22     LL ans=1;
23     for(LL i=2;i<=n;i=j+1)
24     {
25         j=n/(n/i);
26         ans -= (j-i+1LL) * S(n/i);
27     }
28     ansv[n]=ans;
29     return ans;
30 }
31 
32 int main()
33 {
34 //    freopen("test.txt","r",stdin);
35     u[1]=1;
36     for(int i=2;i<=LIM;i++)
37     {
38         if(!v[i])
39         {
40             prime[++tot]=i;
41             u[i]=-1;
42         }
43         for(int j=1;i*prime[j]<=LIM;j++)
44         {
45             v[i*prime[j]]=1;
46             u[i*prime[j]]=u[i]*u[prime[j]];
47             if(i%prime[j]==0)
48             {
49                 u[i*prime[j]]=0;
50                 break;
51             }
52         }
53     }
54     for(int i=2;i<=LIM;i++) u[i]+=u[i-1];
55     LL a,b;
56     cin >> a >> b;
57     cout << S(b)-S(a-1) << endl;
58     return 0;
59 }
View Code

 

同样的方法,由$(\\phi * I)(n) = id(n)$得到

$S(n) = \\frac{n(n+1)}{2} - \\sum_{t=2}^n{S([\\frac{n}{t}])}$

注意n*(n+1)可能炸long long。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring> 
 4 #include <ctime>
 5 #include <map>
 6 #include <cassert>
 7 
 8 #define LL long long
 9 #define LIM 5000000
10 #define P 1000000007LL
11 
12 using namespace std;
13 
14 int tot,prime[LIM+10];
15 LL phi[LIM+10],inv2;
16 bool v[LIM+10];
17 map<LL,LL> ansv;
18 
19 LL S(LL n)
20 {
21     if(n<=LIM) return phi[n];
22     if(ansv.count(n)) return ansv[n];
23     LL j;
24     LL ans=n%P * (n%P + 1LL) %P * inv2%P;
25     assert(ans >=0);
26     for(LL i=2;i<=n;i=j+1)
27     {
28         j=n/(n/i);
29         ans += P - ((j-i+1LL) * S(n/i)%P);
30         if(ans>=P) ans -= P;
31     }
32     ansv[n]=ans;
33     return ans;
34 }
35 
36 LL qpow(LL x,int n)
37 {
38     LL ans=1;
39     for(;n;n>>=1,x=x*x%P) if(n&1) ans=ans*x%P;
40     return ans;
41 }
42 
43 int main()
44 {
45 //    freopen("test.txt","r",stdin);
46     phi[1]=1;
47     for(int i=2;i<=LIM;i++)
48     {
49         if(!v[i])
50         {
51             prime[++tot]=i;
52             phi[i]=i-1;
53         }
54         for(int j=1;i*prime[j]<=LIM;j++)
55         {
56             v[i*prime[j]]=1;
57             phi[i*prime[j]]=phi[i]*phi[prime[j]];
58             if(i%prime[j]==0)
59             {
60                 phi[i*prime[j]]=phi[i]*prime[j];
61                 break;
62             }
63         }
64     }
65     inv2=qpow(2,P-2);
66     for(int i=2;i<=LIM;i++)
67     {
68         phi[i]=phi[i]+phi[i-1];
69         if(phi[i]>=P) phi[i] -= P;
70     }
71     LL n;
72     cin >> n;
73     cout << S(n) << endl;
74     return 0;
75 }
View Code

 

以上是关于Mertens的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数