在C ++中有效计数O(n ^(1/3))中的数字的除数

时间:2018-10-31 15:51:12

标签: c++ algorithm debugging coding-efficiency

我在这里找到了一种有效的算法来计算O(n ^(1/3))中的数字的除数:https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/keyboard-accessibility

我已经在下面的代码中实现了该算法。但这不能正常工作。

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pb push_back
#define endl "\n"
#define pi 2*acos(0)

#define debug(s) cout << #s << " = " << s << endl
#define all(v) (v).begin(), (v).end()
#define mem(a, val) memset(a, val, sizeof a)

vector<int> prime(10000000, 1); // array size is 10^7
void sieve(ll n){
    prime[0]=prime[1]=0;
    for(ll i=2; i<=sqrt(n); i++){
        if(prime[i]==1){
            for(ll j=2; i*j<=n; j++) prime[i*j]=0;
        }
    }
}
bool isPrime(ll n){
    if(n<2) return false;
    return prime[n];
}

vector<int> primeTable;
ll numberOfDivisors(ll n){
    for(int i=0; i<1000000; i++){
        if(prime[i]==1) primeTable.pb(i);
    }
    ll ans=1;
    for(int i=0; ; i++){
        if(primeTable[i]*primeTable[i]*primeTable[i]>n) break;
        ll cnt=1;
        while(n%primeTable[i]==0){
            n=n/primeTable[i];
            cnt++;
        }
        ans*=cnt;
    }
    double sqn=sqrt(n);
    if(isPrime(n)) ans*=2;
    else if((sqn-floor(sqn))==0 and isPrime((ll)sqn)) ans*=3;
    else if(n!=1) ans*=4;

    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    ll n;
    cin >> n;
    ll N=cbrt(n);
    sieve(N);
    cout << numberOfDivisors(n) << endl;

    return 0;
}

即,对于15它返回2(应为4),对于100它返回6(应为9),对于999它返回8(是正确的),但是对于9999它再次返回6(应为12)。我认为在第42行和第45行之间出了点问题。但是我找不到该bug。请帮助我找到错误。

1 个答案:

答案 0 :(得分:1)

您在prime处将vector<int> prime(10000000, 1)的初始值设置为1。然后在prime函数中将n的值更新为seive(ll n)。因此,对于n+110000000 prime的值将保持为1。在主函数中,您为sieve(N)运行了ll N=cbrt(n)。因此,您的isPrime(n)是不正确的,因为n可能大于N=cbrt(n)。修正您的代码不错。

从博客文章中,我了解到该算法用于查找长整型整数的因子。他们还提到要检查素数,请使用Miller Rabin。您检查isPrime(n)的方式不适用于大整数。

还要更新此部分(将1000000更改为cbrt(n)):

ll numberOfDivisors(ll n){
    for(int i=0; i<1000000; i++){
        if(prime[i]==1) primeTable.pb(i);
    }