2^64内大整数分解质因子,比之前的模版快
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long LL;
using namespace std;
const int prime[]={0,2,3,5,7,11,13,17,19,23};
LL gcd(LL x, LL y){
return y==0?x:gcd(y, x%y);
}
LL mulmod(const LL &a,LL b,const LL &n){
LL ret=0,tmp=a%n;
while(b>0)
{
if (b&1)
if ((ret+=tmp)>n) ret-=n;
if ((tmp<<=1)>n) tmp-=n;
b>>=1;
}
return ret;
}
LL pow(LL a,LL d,const LL &n)
{
LL res=1;
while (d>0)
{
if (d&1) res=mulmod(res,a,n);
a=mulmod(a,a,n);
d>>=1;
}
return res;
}
bool millerrabin(LL n)
{
if (n==2) return true;
if (n<2||!(n&1)) return false;
int s,k,i;
LL d;
for(s=0,d=n-1;!(d&1);s++,d>>=1);
for(k=1;k<=9&&prime[k]<n;k++)
{
LL x=pow(prime[k],d,n);
if (x==1) continue;
for(i=1;i<s&&x!=n-1;i++)
x=mulmod(x,x,n);
if (x!=n-1) return false;
}
return true;
}
LL a[110];//质因子
int m;//因子个数
LL pollardrho(LL n)//n>1 and n is not a prime number
{//返回的不一定是个质因子
for(int k=1;k<=9&&prime[k]<n;k++)
if (n%prime[k]==0) return prime[k];
LL x=rand()%n;
LL y=x,d;
while(true)
{
x=rand()%n;
y=(mulmod(x,x,n)+1)%n;
d=gcd((y+n-x)%n,n);
while(d==1)
{
x=(mulmod(x,x,n)+1)%n;
y=(mulmod(y,y,n)+1)%n;
y=(mulmod(y,y,n)+1)%n;
d=gcd((y+n-x)%n,n)%n;
}
if (d) break;
}
return d;
}
void factor(LL n)
{
if (n==1) return;
if (millerrabin(n))
{
a[m++]=n;
return;
}
LL d=pollardrho(n);
factor(d);
factor(n/d);
}
int main(){
int T;
LL n, sum, t, tmp, cnt;
scanf("%d", &T);
while(T--){
m=0;
cnt=sum=0;
scanf("%I64d", &n);
if(n==1){
printf("1 1\n");
continue;
}
if(n!=1&&!millerrabin(n)){
factor(n);
}
sort(a, a+m);
t=a[0];tmp=a[0];cnt=1;
for(int i=1; i<m; i++){
if(a[i]==t)tmp*=t;
else {
cnt++;
sum+=tmp;
t=tmp=a[i];
}
}
sum+=tmp;
if(cnt==1)sum/=a[0];
printf("%I64u %I64u\n", cnt, sum);
}
return 0;
}