这道题需要了解素数筛的原理,而不是只是套模板。
需要明白一点,我们在欧拉筛中筛掉合数用的是这个合数的最小值因子。还记得那一步if(i%primes[j]==0) break;吗?这一步就保证我们用的是最小值因子筛掉所有的合数。
我们可以这么理解,当i%primes[j]的时候,i=k*primes[j],这时候,我们如果不break,继续下一个,则i*primes[j+1]=k*priems[j]*primes[j+1]=(i*primes[j+1])*primes,说明现在的i*primes[j+1]的最小质因子其实是primes[j],只要后面i增大了,i*primes[j+1]自然会被筛掉。
对于这道题,我们只需要改下筛法,记录下最小值因子就行了。
相似题目:CF1047C
AC代码
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=3e7+10;
int n;
int primes[maxn],tot;
int vis[maxn];
int fac[maxn];
void init(){
for(int i=2;i<maxn;i++){
if(!vis[i]) primes[tot++]=i,fac[i]=i;
for(int j=0;j<tot&&primes[j]*i<maxn;j++){
fac[i*primes[j]]=primes[j];
vis[i*primes[j]]=1;
if(i%primes[j]==0) break;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//===========================================================
read(n);
init();
int ans=0;
/*rep(i,1,10){
cerr<<fac[i]<<" ";
}
cerr<<endl;*/
rep(i,1,n) ans+=fac[i]/*,cerr<<fac[i]<<endl*/;
write(ans);
//===========================================================
return 0;
}
京公网安备 11010502036488号