分解质因数+唯一分解定理+所有因数之和

唯一分解定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=p_{1}^{a1}\times p_{2}^{a2}\times p_{3}^{a3}\times p_{4}^{a4}\times\cdots \times p_{n}^{an} 这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。

求所有因数之和:\fn_phv S=(1+p_{1}^{1}+p_{1}^{2}+\cdots +p_{1}^{a1})\times (1+p_{2}^{1}+p_{2}^{2}+\cdots +p_{2}^{a2})\times \cdots \times (1+p_{n}^{1}+p_{n}^{2}+\cdots +p_{n}^{an}),其中(1+p_{n}^{1}+p_{n}^{2}+\cdots +p_{n}^{a_{n}})=\frac{(1-p_{n}^{a_{n}+1})}{1-p_{n}}

分解质因数,一个数n的质因数只能全部小于等于sqrt(n),或者只有一个大于sqrt(n)

        map<int,long long>q;
        for(int j=2;j<=mid;++j)
        {
            int sum=0;
            while(a%j==0)
            {
                a/=j;
                sum++;
            }
            if(sum)
            {
            q[j]+=sum;
            }
            if(a==1)
            break;
        }
        if(a!=1)
        q[a]++;

 n!分解质因数

  对某个质因子p,指数等于n/p+n/(p^2)+n/(p^3)+...

ll cal(ll x,ll y)
{
    ll res=0;
    while(x)
    {
        x/=y;
        res+=x;
    }
    return res;
}

  Pollard-Rho分解质因数,复杂度O(n^0.25)

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+16,maxm=1e6+16;
int prime[N];//1-N质数
ll p[maxm],fac[maxm];
int cnt;     //多组输入注意初始化cnt = 0
inline ll mul(ll a,ll b,ll mod)
{             //WA了尝试改为__int128或慢速乘
    if(mod<=1000000000) return a*b%mod;
    return (a*b-(ll)((long double)a/mod*b+1e-8)*mod+mod)%mod;
}
void init(){
    int tot=0;;
    for(int i=1;i<N;++i) p[i]=i;
    for(int i=2;i<N;++i)
    {
        if(p[i]==i) prime[tot++]=i;
        for(int j=0;1ll*i*prime[j]<N;++j)
        {
            p[i*prime[j]]=prime[j];
            if(i%prime[j]==0) break;
        }
    }
}
ll powl(ll a,ll x,ll mod){
    ll res=1;
    while(x){
        if(x&1) res=mul(res,a,mod);
        a=mul(a,a,mod);
        x>>= 1;
    }
    return res;
}
bool check(ll a,ll n){                       //二次探测原理检验n
    ll t=0,u=n-1;
    while(!(u&1)) {t++;u>>=1;}
    ll x=powl(a,u,n),xx=0;
    while(t--)
    {
        xx=mul(x,x,n);
        if(xx==1&&x!=1&&x!=n-1) return false;
        x=xx;
    }
    return xx==1;
}
bool miller(ll n,int k){
    if(n==2) return true;
    if(n<2||!(n&1)) return false;
    if(n<N) return p[n] == n;
    for(int i=0;i<=k;++i){               //测试k次
        if(!check(rand()%(n-1)+1,n)) return false;
    }
    return true;
}
inline ll gcd(ll a,ll b)
{return b==0?a:gcd(b,a%b);}
inline ll Abs(ll x)
{return x<0?-x:x;}
ll Pollard_rho(ll n)
{
    ll s=0,t=0,c=rand()%(n-1)+1,v=1,ed=1;
    while(1)
    {
        for(int i=1;i<=ed;++i)
        {
            t=(mul(t,t,n)+c)%n;
            v=mul(v,Abs(t-s),n);
            if(i%127==0){
                ll d=gcd(v,n);
                if(d>1) return d;
            }
        }
        ll d=gcd(v,n);
        if(d>1) return d;
        s=t;v=1;ed<<=1;           
    }
}
void getfactor(ll n)
{                          //得到所有的质因子(可能有重复的)
    if(n<N)
    {
        while(n!=1) {fac[cnt++]=p[n];n/=p[n];}
        return;
    }
    if(miller(n,6)) fac[cnt++]=n;
    else
    {
        ll d=n; while(d>=n) d=Pollard_rho(n);
        getfactor(d);getfactor(n/d);
    }
}
int main()
{
    //freopen("1.txt","r",stdin);
    init();
    ll x;
    cin>>x;//分解x
    cnt=0;
    getfactor(x);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值