数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
2014-09-02 22:55
471 查看
Prime Test
Description
Given a big integer number, you are required to find out whether it's a prime number.
Input
The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).
Output
For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.
Sample Input
Sample Output
Source
POJ Monthly
略。
[b]analyse:[/b]
输入的n很大,我们不可能再用筛法来求素数,这时Miller_Rabin算法就显得尤为重要。
若n不是素数,需要进行质因数分解,同样的问题,n很大,我们不可能用试除法来进行质因数分解,那样必会tle。这时就必须使用pollard_rho算法来进行质因数分解。
其实Miller_Rabin算法和pollard_rho算法很多时候是组合在一起用的。
[b]Time complexity:[/b]O(n) 一般情况下是O(n)
[b]Source code:[/b]
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 29046 | Accepted: 7342 | |
Case Time Limit: 4000MS |
Given a big integer number, you are required to find out whether it's a prime number.
Input
The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).
Output
For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.
Sample Input
2 5 10
Sample Output
Prime 2
Source
POJ Monthly
[b]Mean:[/b]
略。
[b]analyse:[/b]
输入的n很大,我们不可能再用筛法来求素数,这时Miller_Rabin算法就显得尤为重要。
若n不是素数,需要进行质因数分解,同样的问题,n很大,我们不可能用试除法来进行质因数分解,那样必会tle。这时就必须使用pollard_rho算法来进行质因数分解。
其实Miller_Rabin算法和pollard_rho算法很多时候是组合在一起用的。
[b]Time complexity:[/b]O(n) 一般情况下是O(n)
[b]Source code:[/b]
//Memory Time // 1347K 0MS // by : Snarl_jsb #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<climits> #include<cmath> #define N 1000010 #define LL long long using namespace std; //**************************************************************** // Miller_Rabin 算法进行素数测试 //速度快,而且可以判断 <2^63的数 //**************************************************************** const int S=20; //随机算法判定次数,S越大,判错概率越小 //计算 (a*b)%c. a,b都是long long的数,直接相乘可能溢出的 // a,b,c <2^63 long long mult_mod(long long a,long long b,long long c) { a%=c; b%=c; long long ret=0; while(b) { if(b&1){ret+=a;ret%=c;} a<<=1; if(a>=c)a%=c; b>>=1; } return ret; } //计算 x^n %c long long pow_mod(long long x,long long n,long long mod)//x^n%c { if(n==1)return x%mod; x%=mod; long long tmp=x; long long ret=1; while(n) { if(n&1) ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret; } //以a为基,n-1=x*2^t a^(n-1)=1(mod n) 验证n是不是合数 //一定是合数返回true,不一定返回false bool check(long long a,long long n,long long x,long long t) { long long ret=pow_mod(a,x,n); long long last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true;//合数 last=ret; } if(ret!=1) return true; return false; } // Miller_Rabin()算法素数判定 //是素数返回true.(可能是伪素数,但概率极小) //合数返回false; bool Miller_Rabin(long long n) { if(n<2)return false; if(n==2)return true; if((n&1)==0) return false;//偶数 long long x=n-1; long long t=0; while((x&1)==0){x>>=1;t++;} for(int i=0;i<S;i++) { long long a=rand()%(n-1)+1;//rand()需要stdlib.h头文件 if(check(a,n,x,t)) return false;//合数 } return true; } //************************************************ //pollard_rho 算法进行质因数分解 //************************************************ long long factor[100];//质因数分解结果(刚返回时是无序的) int tol;//质因数的个数。数组小标从0开始 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 Pollard_rho(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=(mult_mod(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 n) { if(Miller_Rabin(n))//素数 { factor[tol++]=n; return; } long long p=n; while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1); findfac(p); findfac(n/p); } int main() { //srand(time(NULL));//需要time.h头文件//POJ上G++不能加这句话 long long n; long long t; cin>>t; while(t--) { scanf("%I64d",&n); if(n==1) continue; if(Miller_Rabin(n))printf("Prime\n"); else { tol=0; findfac(n); long long minn=INT_MAX; for(int i=0;i<tol;i++) { if(factor[i]<minn) { minn=factor[i]; } } printf("%I64d\n",minn); } } return 0; }
相关文章推荐
- 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test
- poj 1811 + poj 2429 (Miller_Rabin大素数测试 + Pollard_Rho大合数分解)
- Poj 1811 Prime Test 素数测试 Miller-Rabin 与 整数的因子分解 Pollard rho
- POJ 1181 大整数是否为素数以及求大整数的质因数-数论-(Miller_rabin+Pollard_rho)
- hihoCoder 九十二周 数论一·Miller-Rabin质数测试 (数论 筛素数)
- POJ 1811 大整数素数判断 Miller_Rabin
- POJ 2429 -- miller-rabin素数测试,Pollard_rho素因子分解
- 20140915 【 数论 - Miller_Rabin素数测试 】 51nod 1106 . 质数检测
- POJ 1811 Prime Test --- Miller 素数测试
- Miller_Rabin素数测试
- POJ1811 miller-rabin素数测试pollard-rho质因子分解
- Miller_Rabin大素数测试与Pollard_rho整数分解模版
- POJ 1811 Miller_Rabin+Pollard_Rho
- POJ 1811 Prime Test(Miller-Rabin & Pollard-rho素数测试)
- Miller_Rabin素数测试[Fermat小定理][二次探测定理][同余式][Wilson定理]
- Miller__Rabin素数测试
- poj 1811 Prime Test(数论:大素数判定-分解)
- Miller_Rabin素数测试
- Miller - Rabin素数测试
- Miller_Rabin素数测试