接触到了这一道题,才知道筛素数除了埃氏筛 还有更快的 欧拉筛(线性筛)
线性筛的主要代码
#define maxn 30000000+100
ll ans=0;
int visit[maxn],prime[maxn];
void getanswer(int n) {
memset(visit,0,sizeof(visit));//刚开始假设所有数都是质数,然后依次筛去
int cnt=0;//记录质数的个数
for(int i=2; i<=n; i++) {
if(!visit[i]) prime[cnt++]=i;//找到质数
for(int j=0;j<cnt&&prime[j]*i<=n;j++){//从最小的质数开始依次枚举找他的最小质因子
visit[i*prime[j]]=1;
if(i%prime[j]==0) break;//prime[j]是i的最小质因子,如果不跳出 还会加上后面的质因子 ,这一行尤为重要
}
}
}
附上学习的博客 讲得很不错
然后是这道的解法
#include<iostream>
#include<cstring>>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 30000000+100
ll ans=0;
int visit[maxn],prime[maxn];
void getanswer(int n) {
memset(visit,0,sizeof(visit));
int cnt=0;
for(int i=2; i<=n; i++) {
if(!visit[i]) prime[cnt++]=i,ans+=i;
for(int j=0;j<cnt&&prime[j]*i<=n;j++){
visit[i*prime[j]]=1;
ans+=prime[j];
if(i%prime[j]==0) break;//prime[j]是i的最小质因子,如果不跳出 还会加上后面的质因子
}
}
}
int main() {
ios::sync_with_stdio(false);
int n;
cin>>n;
getanswer(n);
cout<<ans<<endl;
return 0;
}