唯一分解定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。
求所有因数之和:,其中
分解质因数,一个数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;
}