质因子分解

今天没事做,我们来写个博客,混混等级!得意下面我们来解释质因子分解。

我们以求数的质因子的个数为例来讲解。

对于质因子分解最简单最纯粹的暴力我相信大家都会的。

int getnum(int x)
{
    int ans=0;
    for(int i=2;i*i<=x;i++)
    {
        while(x%i==0)
        {
            ans++;
            x/=i;
        }
    }
    return ans;
}

但是当处理的数据比较多,而且范围也比较大的时候显然这种方式就不再那么适合了。

既然我们是分解质因子,那么我们就可以先预处理出在范围内的所有素数,我们筛的时候用素数来筛选!

#define nn 1000010
bool vis[nn];
int k,p[nn],f[nn];
void init()
{
    memset(vis,false,sizeof(vis));
    vis[1]=true;
    for(int i=2;i*2<=nn;i++)
        if(!vis[i])
            for(int j=i*i;j<=nn;j+=i)
                vis[j]=true;
    k=0;
    for(int i=2;i<nn;i++)
        if(!vis[i])
            p[k++]=i;
}
int getnum(int x)
{
    int ans=0;
    for(int i=0;p[i]*p[i]<=x;i++)
    {
        while(x%p[i]==0)
        {
            ans++;
            x/=p[i];
        }
        if(!vis[x])
        {
            ans++;
            break;
        }
    }
    return ans;
}

当然也可以用这种方式来预处理x小于nn的所有数的质因子个数。

#define nn 1000010
bool vis[nn];
int k,p[nn],f[nn];
void init()
{
    memset(vis,false,sizeof(vis));
    vis[1]=true;
    for(int i=2;i*2<=nn;i++)
        if(!vis[i])
            for(int j=i*i;j<=nn;j+=i)
                vis[j]=true;
    k=0;
    for(int i=2;i<nn;i++)
        if(!vis[i])
            p[k++]=i;
}
int getnum(int x)
{
    int ans=0;
    for(int i=0;p[i]*p[i]<=x;i++)
    {
        while(x%p[i]==0)
        {
            ans++;
            x/=p[i];
        }
        if(!vis[x])
        {
            ans++;
            break;
        }
    }
    return ans;
}
void getsnum()
{
    f[1]=0;
    for(int i=2;i<nn;i++)
    {
        if(!vis[i]) f[i]=1;
        else f[i]=getnum(i);
    }
}

用这种方式来预处理小于nn的所有数的质因子个数的方式,我在本地跑用了大概0.125s。

上面的方式不仅可以求个数,也可以求出他的质因子是那些数。

下面我们来介绍一种很快算出质因子个数的姿势,但是只能算出个数而已,并不能算出是他的质因子是那些数。

它的思想基于素筛,复杂度和素筛的差不多。


#define nn 1000010
int f[nn];
void init()
{
    memset(f,0,sizeof(f));
    for(int i=2;i<nn;i++)
    {
        while(f[i]) i++;
        f[i]=1;
        for(int j=2;j*i<=nn;j++)
            f[i*j]=f[j]+1;
    }
}

 

就是这么简单,是不是没想到呀。大笑 

当然这种思想还可以求出它不同质因子的个数。处理方式相近,只是多了个if....else..而已

#define nn 1000010
int f[nn];
void init()
{
    memset(f,0,sizeof(f));
    for(int i=2;i<nn;i++)
    {
        while(f[i]!=0)
            i++;
        f[i]=1;
        for(int j=2;j*i<=nn;j++)
        {
            if(j%i==0)
                f[i*j]=f[j];
            else
                f[i*j]=f[j]+1;
        }
    }
}

如果有什么错误,还麻烦告诉我一下,我也好修改。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值