大素数的判定,用拉宾-米勒素数测试,但是我竟然也加上了RHO,地址: http://acm.pku.edu.cn/JudgeOnline/problem?id=1811
/** *//******************************************************************************************* 这里包含了rabinmiller素数测试与pollard算法求解最小质因数的方法,函数说明放到每个函数的前面 *******************************************************************************************/
#include <stdio.h> #include <stdlib.h> typedef unsigned __int64 hugeint; //求出最大公约数 hugeint gcd(hugeint A, hugeint B) { while (A != 0) { hugeint C = B % A; B = A; A = C; } return B; }
//求a*b%c,要求:a,b的范围在hugeint范围的一般以内,在hugeint为unsigned __int64时,a,b需要是__int64能表示的数 hugeint product_mod(hugeint A, hugeint B, hugeint C) { hugeint R, D; R = 0; D = A; while (B > 0) { if ( B&1 ) R = (R + D) % C; D = (D + D) % C; B >>=1; } return R; }
//求a^b%c,要求:a,b的范围在hugeint范围的一般以内,在hugeint为unsigned __int64时,a,b需要是__int64能表示的数 hugeint power_mod(hugeint A, hugeint B, hugeint C) { hugeint R = 1, D = A; while (B ) { if (B&1) R = product_mod(R, D, C); D = product_mod(D, D, C); B >>=1; } return R; }
//给出随机数,可以简单的用rand()代替 hugeint rAndom() { hugeint a; a = rand(); a *= rand(); a *= rand(); a *= rand(); return a; }
//rabinmiller方法测试n是否为质数 int pri[]={2,3,5,7,11,13,17,19,23,29}; bool isprime(hugeint n) { if(n<2) return false; if(n==2) return true; if(!(n&1)) return false; hugeint k = 0, i, j, m, a; m = n - 1; while(m % 2 == 0) m = (m >> 1), k++; for(i = 0; i < 10; i ++) { if(pri[i]>=n)return 1; a = power_mod( pri[i], m, n ); if(a==1) continue; for(j = 0; j < k; j ++) { if(a==n-1)break; a = product_mod(a,a,n); } if(j < k) continue; return false ; } return true; }
//pollard_rho分解,给出N的一个非1因数,返回N时为一次没有找到 hugeint pollard_rho(hugeint C, hugeint N) { hugeint I, X, Y, K, D; I = 1; X = rand() % N; Y = X; K = 2; do { I++; D = gcd(N + Y - X, N); if (D > 1 && D < N) return D; if (I == K) Y = X, K *= 2; X = (product_mod(X, X, N) + N - C) % N; }while (Y != X); return N; }
//找出N的最小质因数 hugeint rho(hugeint N) { if (isprime(N)) return N; do { hugeint T = pollard_rho(rand() % (N - 1) + 1, N); if (T < N) { hugeint A, B; A = rho(T); B = rho(N / T); return A < B ? A : B; } } while (true); }
int main () {
int t; hugeint n, ans;
scanf ( "%d", &t ); while ( t -- ) { scanf ( "%I64d", &n );
ans = rho ( n ); if ( ans == n ) { printf ( "Prime\n" ); } else { printf ( "%I64d\n", ans ); } } return 0; }
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
公告
决定从线程开始!!
常用链接
留言簿(6)
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|