【问题标题】:How to modify the sieve approach to count the factors of a number less than a given n?如何修改筛法以计算小于给定 n 的数字的因子?
【发布时间】:2021-05-11 10:14:04
【问题描述】:

好的,所以我试图找到比 O(sqrt(n)) 更好的时间因子,这让我查找了 Sieve 方法。现在我试图找到小于给定 n(n

#include <bits/stdc++.h>

#define lli long long int

using namespace std;

const int Max=1000001;

lli prime[Max];

void sieveGen()
{
    prime[0]=0;
    prime[1]=1;

    for(lli i=2;i<Max;i++)
    {
        prime[i]=i;
    }
    for(lli i=4;i<Max;i+=2)
    {
        prime[i]=2;
    }

    for(lli i=3;i<Max;i++)
    {
        if(prime[i]==i)
        {
            if(i*i>Max)
            {
                break;
            }
            for(lli j=i*i;j<Max;j+=i)
            {

                if(prime[j]==j)
                {
                    prime[j]=i;
                }
            }
        }
    }
}


lli count_factors(lli num,lli i)
{
    if(i==2)
    return 1;
    
    
    if(i==3)
    {
        if(num%2==0)
        {
            return 2;
        }
        else
        {
            return 1;
        }
    }
    
    lli ans=1;
    
    lli count=1;
    lli first_prime=prime[num];
    lli second_prime=num/prime[num];
    
    
    while(second_prime!=1&&firstprime<i)
    {
        if(prime[second_prime]==first_prime)
        {
            count++;

        }
        else
        {
            first_prime=prime[second_prime];
            ans=ans*(count+1);
            count=1;
        }
        second_prime=second_prime/prime[second_prime];
        if(first_prime<i)
        {
            ans=ans*(count+1);
        }
    }
   
    return ans;
}

int main() {

    sieveGen();
    
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t;
    cin>>t;
    while(t--)
    {
        lli N,M,res=0;
        cin>>N>>M;
        
        if(M==1)
        {
            res+=N-1;
        }
        else
        {
           for(lli i=2;i<=N;i++)
           {
               lli num=M-(M%i);
               if(num>0)
               {
                  cout<<i<<"."<<count_factors(num,i)<<"\n";
                  res+=count_factors(num,i); 
               }
               else
               {
                   res+=(i-1);
               }
           }
        }
       
      cout<<res<<"\n";
    }
    
    return 0;
}

在这里,我想找出小于inum的因子个数。

这对于任何素数 i 都可以正常工作,但对于其他一些数字(例如 6)则失败。

非常感谢任何帮助。

【问题讨论】:

  • 这个函数怎么调用? prime 是什么?
  • 我用完整的代码编辑了帖子。 prime 是一个数的所有最小素因数中的筛子。
  • 那为什么是prime[1]=1? 1 不是素数...
  • 因为我们正在运行从 2 到 N 的代码,所以永远不会遇到 prime[1]。我就这样保持着。
  • 素数分解?因此,当它达到 1 时,我们知道不再可能对数字进行素因数分解

标签: algorithm factors


【解决方案1】:

除数的SoE是这样的:

  1. 初始化SoE[n]数组

    所以使用0 分配和清除大小为n 的一维整数数组,其中n-1 是您要查询的最大值。

  2. 对于从2n-1 的每个数字i 计算SoE

    所以简单地增加所有SoE[j] 其中j=i,2*i,3*i,4*i,...

  3. 现在SoE[x] 持有x 的分割数

    不是会计1,而是会计i,所以如果您不想只使用递减值。

对于 n=13 的示例,SoE 将如下所示:

x | SoE[x]
--+-------
1 | 0
2 | 1
3 | 1
4 | 2
5 | 1
6 | 3
7 | 1
8 | 3
9 | 2
10| 3
11| 1
12| 5

所以对于x=12SoE[12]=5,如果您不想考虑x本身,请使用5-1=4分隔符(2,3,4,6)

如果您还想要除法器本身(而不仅仅是它们的计数),那么您可以将除法而不是计数的所有数字的列表存储在 SoE 中

x | SoE[x]
--+-------
1 | 
2 | 2
3 | 3
4 | 2,4
5 | 5
6 | 2,3,6
7 | 7
8 | 2,4,8
9 | 3,9
10| 2,5,10
11| 11
12| 2,3,4,6,12

同样,如果您不想考虑 x 本身,您可以忽略 SoE[x] 列表中的最后一个元素。

素数分解与此几乎相同,只是您在项目符号 #2 中仅使用素数作为 i

【讨论】:

  • 感谢您的回答。我认为最好的方法是创建一组地图。数组的第 i 个单元将代表第 i 个数字。该映射将具有作为数字因子的键,并且每次数字是因子时,它将存储前一个键+1的值。所以 12 看起来像这样:{{2:1, 3:2, 4:3, 6:4}}
猜你喜欢
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
相关资源
最近更新 更多