J题:Sum

题目链接:

https://nanti.jisuanke.com/t/30999

代码:

线性筛找出最小的素数来,之后递推找规律求解。

#include <iostream>
#include <cstring>
using namespace std;
const int inf=2e7+10;      
int flag[inf+10],ans[inf+10];
int temp[inf+10];

int main()
{
    int k=0;
    memset(flag,0,sizeof(flag));     //所有的素数都是可以分解为是一连串的质数之积。 
    for(int i=2;i<=inf;i++)            
    {
        if(!flag[i])
        {
            ans[k++]=i;
            temp[i]=i;                 
        }
        for(int j=0;j<k;j++)
        {
            if(i*ans[j]>inf)          
                break;
            flag[i*ans[j]]=1;        
            temp[i*ans[j]]=ans[j];    
            if(i%ans[j]==0)          //尽快的跳出。 
            {
                break;                 
            }                      
        }
    }
    /*for(int i=0;i<k;i++)             
        cout<<ans[i]<<" ";  
    cout<<endl;*/
    memset(ans,-1,sizeof(ans));                       
    ans[0]=0;                      
    ans[1]=1; ans[2]=2; ans[3]=2;ans[4]=1; 
    int minprime;
    for(int i=5; i<inf ; ++i)         
    {
        minprime=temp[i];           
        if(minprime*minprime*minprime<=i && i%(minprime*minprime*minprime)==0 )
            ans[i]=0;
        else if( minprime*minprime<=i&&i%(minprime*minprime)==0 )   
            ans[i]=ans[i/( minprime*minprime)  ]    ;
        else
            ans[i]=2*ans[i/minprime];
    }   
    for(int i=1;i<=inf;i++)
        ans[i]=ans[i]+ans[i-1];
    int T,a;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&a);
        printf("%d\n",ans[a]);
    }
    return 0;    

猜你喜欢

转载自blog.csdn.net/weixin_40799464/article/details/82430076