BZOJ 4805: 欧拉函数求和 杜教筛

https://www.lydsy.com/JudgeOnline/problem.php?id=4805

给出一个数字N,求sigma(phi(i)),1<=i<=N

https://blog.csdn.net/popoqqq/article/details/45023331 ←杜教筛的一些讲解

杜教筛用来求积性函数前缀和,本题同bzoj 3944,bzoj 3944多了一个求sigma( μ ( i ) )

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
const int maxn=;
LL n;
LL phi[maxn]={};
LL pri[maxn/]={},tot=;
bool v[maxn]={};
void get_phi(int m){
phi[]=;
for(int i=;i<=m;++i){
if(!v[i]){pri[++tot]=i;phi[i]=i-;}
for(int j=;j<=tot&&pri[j]*i<=m;++j){
int w=pri[j]*i;v[w]=;
if(i%pri[j]==){phi[w]=phi[i]*pri[j];break;}
phi[w]=phi[i]*(pri[j]-);
}
}
//for(int i=1;i<=10;++i)cout<<phi[i]<<endl;
for(int i=;i<=m;++i){
phi[i]+=phi[i-];
}
}
LL solve(LL m){
if(m<=maxn-)return phi[m];
LL ans=m*(m+)/;
for(LL i=,las;i<=m;i=las+){
las=m/(m/i);
ans-=(LL)(las-i+)*solve(m/i);
}
return ans;
}
int main(){
get_phi(maxn-);
scanf("%lld",&n);
printf("%lld\n",solve(n));
return ;
}
上一篇:[js]设计模式小结&对原型的修改


下一篇:rest_framework之规范详解 00