最小質因數和


這題實在是比較一棵賽艇就發上來好了。

題目:

給定n,求出小於等於n的所有合數的最小質因數之和。

對於70%的數據,n<=10^7。

對於100%的數據,n<=10^9。

題解:

70% 線篩大法好

100%

首先我們考慮對於每一個小於等於sqrt(n)的質數容斥,然后稍微推一推就可以得到一個比較靠譜的容斥方法,雖然復雜度玄學但是似乎跑得蠻快的。然后我們測一下時間……真是不巧n=10^9要跑2s左右。(我就是這么被卡掉的

標程是這樣的:

我們定一個閥值k=100,對於<=k的質因數(一共也就才幾十個)我們用科學的容斥搞一搞,這個復雜度基本沒有。

對於>=k的質因數p我們可以發現n/p是在10^7以內的。然后為了保證質因數是最小的,我們必須只能選n不是<p質數的倍數的。那么我們發現n/p顯然也要不是<p質數的倍數。

這樣我們用一個暴力篩法來維護n/p,具體做法是因為p遞增時n/p遞減,那么我們考慮線篩的上界也是遞減的,每次線篩賦值bool數組的時候順便更新一下答案,減小上界的時候就把多的答案扣掉。既然1kw的暴力篩法可以過,這樣顯然是科學的。

n=10^9只要跑0.1s左右。事實上如果把k設成1000跑n=10^10也只要跑0.6s左右。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <time.h>
#include <limits>
#include <set>
#include <map>
using namespace std;
int sq,n;
#define FJ 100 //1000?
#define ZS 10000005
bool yz[ZS+3];
int mn=ZS,cnt=0;
bool isprime(int x)
{
    for(int p=2;p*p<=x;p++)
    {
        if(x%p==0) return 0;
    }
    return 1;
}
int pn=0,ps[233333];
long long ans=0;
void dfs(int x,int lst,int dep)
{
    if(lst!=0)
    {
        ans+=n/x*(long long)ps[lst]*dep;
        if(x==ps[lst]) ans-=x;
    }
    for(int i=lst+1;i<=pn;i++)
    {
        if(ps[i]<=FJ&&(long long)x*ps[i]<=n) dfs(x*ps[i],i,-dep);
        else break;
    }
}
void xj(int p)
{
    while(mn>p) cnt-=yz[mn--];
}
void pj(int p)
{
    for(int j=p;j<=mn;j+=p)
    {
        if(yz[j]) continue;
        yz[j]=1; ++cnt;
    }
}
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
int main()
{
    //FO(prime)
    scanf("%d",&n);
    sq=sqrt(n)+1;
    int cc=0;
    for(int i=2;i<=sq;i++)
    {
        if(isprime(i)) ps[++pn]=i;
    }
    dfs(1,0,-1);
    for(int i=1;i<=pn;i++)
    {
        int cur=ps[i];
        if(cur>FJ)
        {
            xj(n/cur);
            ans+=(n/cur-cnt-1)*(long long)cur;
        }
        pj(cur);
    }
    printf("%lld\n",ans);
}

嗯今天閆神還立了一個flag,說不會求質數的答案。那我們就是要求n以內質數的和。

丟鏈接跑 http://mathoverflow.net/questions/81443/fastest-algorithm-to-compute-the-sum-of-primes


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM