其实不过是大整数分解。。。
注意两点:注意L 不能==N
但是,N却可以是素数。。。囧
#include <iostream> #include <cstdio> #include <algorithm> #include <cstdio> #define LL __int64 #define MAX 1LL<<61 #define Times 8 #define N 501 #define C 101 using namespace std; LL cop[N]; int ct; bool cmp(LL a,LL b){ if(a<b) return true; return false; } LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b); } LL random(LL n){ return (LL)((double)rand()/RAND_MAX*n+0.5); } LL multi(LL a,LL b,LL m){ //a*b%m LL ret=0; while(b){ if(b&1) ret=(ret+a)%m; b>>=1; a=(a<<1)%m; } return ret; } LL quick(LL a,LL b,LL m){ LL ans=1; a%=m; while(b){ if(b&1){ ans=multi(ans,a,m); b--; } b/=2; a=multi(a,a,m); } return ans; } bool Witness(LL a,LL n){ LL m=n-1; int j=0; while(!(m&1)){ j++; m>>=1; } LL x=quick(a,m,n); if(x==1||x==n-1) return false; while(j--){ x=multi(x,x,n); if(x==n-1) return false; } return true; } bool Miller_Rabin(LL n){ if(n<2) return false; if(n==2) return true; if(!(n&1)) return false; for(int i=1;i<=Times;i++){ LL a=random(n-2)+1; if(Witness(a,n)) return false; } return true; } LL Pollard_Rho(LL n,int c){ LL x,y,d,i=1,k=2; x=random(n-1)+1; y=x; while(true){ i++; x=(multi(x,x,n)+c)%n; d=gcd(y-x,n); if(d>1&&d<n){ return d; } if(y==x) return n; if(i==k){ y=x; k=k<<1; } } } void find(LL n,int k){ if(n==1) return ; if(Miller_Rabin(n)){ cop[++ct]=n; return ; } LL p=n; while(p>=n) p=Pollard_Rho(p,k--); find(p,k); find(n/p,k); } int main(){ int T; LL n; scanf("%d",&T); while(T--){ scanf("%I64d",&n); ct=0; find(n,C); sort(cop+1,cop+1+ct,cmp); if(ct==1){ printf("1 1\n"); continue; } LL cnt=0;LL tmp=0; LL ans=0; cop[0]=1; cop[++ct]=1; for(int i=1;i<=ct;i++){ if(cop[i]!=cop[i-1]){ ans+=tmp; tmp=cop[i]; cnt++; } else{ tmp*=cop[i]; } } if(ans==n) ans/=cop[1]; printf("%I64d %I64d\n",cnt-1,ans); } return 0; }
时间: 2024-11-08 20:07:50