依然是pollard_rho和Miller_Rabin的模版。。。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int PRIME[9]={2,3,5,7,11,13,17,19,23}; typedef long long LL; LL ans1,ans2,tmp,n,dig[200]; int Case,cnt; LL mult(LL a,LL b,LL Mod){ LL ret=0; for (;b>0;b>>=1){ if (b&1) ret=(ret+a)%Mod; a=(a+a)%Mod; } return ret; } LL qck(LL a,LL b,LL Mod){ LL ret=1; for (;b>0;b>>=1){ if (b&1) ret=mult(ret,a,Mod); a=mult(a,a,Mod); } return ret; } bool WITNESS(LL a,LL n){ LL t=0, x=n-1; while (!(x&1)) x>>=1, t++; LL d = qck(a,x,n), dd; while (t--){ dd = mult(d,d,n); if (dd==1 && d!=1 && d!=n-1) return 1; d = dd; } return (d!=1); } bool Miller_Rabin(LL n){ if (n<=1) return 0; if (n==2) return 1; if (!(n&1)) return 0; for (int i=0;i<9&&PRIME[i]<n;i++) if (WITNESS(PRIME[i],n)) return 0; return 1; } LL gcd(LL a,LL b){ while (b) b^=a^=b^=a%=b; return a; } LL pollard_rho(LL n,LL c){ LL i=1, k=2, x, y, d; x = y = rand()%n; for (;;i++){ x = (mult(x,x,n)+c)%n; d = gcd(abs(x-y),n); if (d!=1 && d!=n) return d; if (x==y) return n; if (i==k) y=x, k=k*2; } } void solve(LL n){ if (Miller_Rabin(n)){ dig[++cnt]=n; return; } LL p = n; while (p>=n) p = pollard_rho(n,rand()%(n-1)+1); solve(p); solve(n/p); } int main(){ //freopen("hdu4344.in","r",stdin); //freopen("hdu4344.out","w",stdout); scanf("%d",&Case); while (Case--){ scanf("%I64d",&n); cnt=0; memset(dig,0,sizeof(dig)); solve(n); sort(dig+1,dig+cnt+1); ans1 = ans2 = tmp = 0; for (int i=1;i<=cnt+1;i++) if (dig[i]!=dig[i-1]){ ans1++; ans2 += tmp; tmp = dig[i]; } else tmp *= dig[i]; ans1--; if (ans1==1) ans2/=dig[1]; printf("%I64d %I64d\n",ans1,ans2); } return 0; }