数论:min25筛求sum(1,n)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;

const int mxm=2e5+5;
const ll N=1e10+5;

bool isprime[mxm];
ll prime[mxm],w[mxm],id1[mxm],id2[mxm];
ll num_pri=0;
ll m=0;
ll sump[mxm];
ll g[mxm];
ll h[mxm];//h卵用没有 
ll sqr;
ll n,mod;
ll id3(ll x){
    
    
    return x<=sqr?id1[x]:id2[n/x];
}
ll f(int x){
    
    
	return x;
}
ll cal(int x){
    
    
	return x*(x+1)/2;
}
ll fastpow(ll a,ll pow){
    
    
	long long base=a;
	long long ans=1;
	while(pow){
    
    
		if(pow&1){
    
    
			ans=(ans*base);
		}
		base=(base*base);
		pow>>=1;
	}
	return ans;
}
void el(){
    
    
    sqr=sqrt(N);
    isprime[1]=1;
    for(ll i=2;i<=sqr;++i){
    
    
        if(!isprime[i]) prime[++num_pri]=i,sump[num_pri]=sump[num_pri-1]+f(prime[num_pri]);
        for(ll j=1;j<=num_pri&&i*prime[j]<=sqr;++j){
    
    
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}//现在需要解决 第二步的min25筛  
void init(){
    
    
    for(ll i=1;i<=n;i=n/(n/i)+1){
    
    
        w[++m]=n/i;
        if(w[m]<=sqr){
    
    
            id1[w[m]]=m;
        }
        else{
    
     
            id2[n/w[m]]=m;
        }//记录id 
        g[m]=cal(w[m])-1;//2-w[m]  f(x)的和 
        h[m]=f(w[m])-1;//对应的函数值 -1
    }
    for(ll i = 1;i<=num_pri;++i){
    
    
        for(ll j=1; j<=m && 1ll*prime[i]*prime[i] <= w[j]; ++j){
    
    
            g[j]=g[j] -  f(prime[i])* (g[id3(w[j] / prime[i])] - sump[i - 1]);
            h[j]=h[j] -  h[id3( w[j] / prime[i] )];
        }
    }
}
int S(ll x,int y){
    
    
	if(x<=1||prime[y]>x) return 0;
					
	int res=g[id3(x)]-sump[y-1];
	
	for(int i=y;i<=num_pri&&1ll*prime[i]*prime[i]<=x;++i){
    
    
		
		ll t1=prime[i],t2=1ll*prime[i]*prime[i];
		
		for(int e=1;t2<=x;++e,t1=t2,t2*=prime[i])

			res+=1ll*S(x/t1,i+1)*(fastpow(prime[i],e))+(fastpow( prime[i] ,e+1));
	}
	
	return res;
}
int main(){
    
    
    el();
    n=500;
    m=0;
    init();

    ll answer = g[id3(n)] ;
      
    printf("%lld\n", S(n,1)+f(1) );
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45695839/article/details/109823359