菜鳥系列——pollard_rho分解質因子
阿新 • • 發佈:2019-01-07
菜鳥就要老老實實重新學起:
pollard_rho分解質因子:
利用miller-rabin和pollard_rho演算法進行大素數判斷和素因子分解。
模版:
long long factor[1000];//質因數分解結果(剛返回時是無序的) int sum;//質因數的個數。陣列小標從0開始 #define T 100//隨機演算法判定次數,N越大,判錯概率越小 long long modMul(long long a,long long b,long long n) { long long res = 0; while(b) { if(b&1) res = (res + a) % n; a = (a + a) % n; b >>= 1; } return res; } long long modExp(long long x,long long k,long long mod) { long long ans = 1; while(k) { if(k & 1) ans = modMul(ans, x, mod); x = modMul(x, x, mod); k >>= 1; } return ans; } bool millerRabin(long long n) { if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true; if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11)) return false; long long x, pre, u; int i, j, k = 0; u = n - 1; while(!(u&1)) { k++; u >>= 1; } srand((long long)time(0)); for(i = 0; i < T; ++i) { x = rand()%(n-2) + 2; if((x%n) == 0) continue; x = modExp(x, u, n); pre = x; for(j = 0; j < k; ++j) { x = modMul(x,x,n); //二次探測判斷 if(x == 1 && pre != 1 && pre != n-1) return false; pre = x; } //費小判斷 if(x != 1) return false; } return true; } long long gcd(long long a,long long b) { if(a==0)return 1; if(a<0) return gcd(-a,b); while(b) { long long t=a%b; a=b; b=t; } return a; } long long pollardRho(long long x,long long c) { long long i=1,k=2; long long x0=rand()%x; long long y=x0; while(1) { i++; x0=(modMul(x0,x0,x)+c)%x; long long d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(i==k){y=x0;k+=k;} } } //對n進行素因子分解 void findFac(long long x) { srand((long long)time(0)); if(millerRabin(x))//素數 { factor[sum++]=x; return; } long long p=x; while(p>=x) p=pollardRho(p,rand()%(x-1)+1); findFac(p); findFac(x/p); }