POJ 1811 Prime Test(大素数判断+大合数素因子分解)
发布时间:2020-12-14 02:21:05 所属栏目:大数据 来源:网络整理
导读:题意:判断n(n2^54)是否为素数,如果不是,那么输出n最小的因子。 思路:这题肯定不能用普通的枚举来做, 对于判断大素数,可以用Miller_Rabin随机算法进行素性检验,而分解素因数可以使用Miller_Rabin搭配Pollard_rho算法进行分解,Miller_Rabin算法出错的
|
题意:判断n(n<2^54)是否为素数,如果不是,那么输出n最小的因子。 思路:这题肯定不能用普通的枚举来做, 对于判断大素数,可以用Miller_Rabin随机算法进行素性检验,而分解素因数可以使用Miller_Rabin搭配Pollard_rho算法进行分解,Miller_Rabin算法出错的概率小于2^(-s),s为测试的数据个数,如果不放心的话可以多试几组,在实际应用中是一种很好的随机化算法,Pollard_rho算法理论复杂度在O(n^(1/4))左右,实际中表现也很好, ps:看了算法导论好久.....终于弄懂,整理了一个模板。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define LL long long
#define pii pair<int,int>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
const int maxn = 10000 + 5;
const int S = 20;
LL factor[maxn];
int tot;
LL multi_mod(LL a,LL b,LL c) {
a %= c; b %= c;
LL ret = 0;
while(b) {
if(b&1) {
ret += a;
if(ret >= c) ret -= c;
}
a <<= 1; b >>= 1;
if(a >= c) a-=c;
}
return ret;
}
//返回a^p mod n,要求0 <= a < n
LL pow_mod(LL a,LL p,LL n) {
if(p == 0) return 1;
LL ans = pow_mod(a,p/2,n);
ans = multi_mod(ans,ans,n);
if(p&1) ans = multi_mod(ans,a,n);
return ans;
}
//判断n是否是合数,是的话返回1,否则返回0
bool check(LL a,LL n,LL x,LL t) {//以a为基,n-1=x*2^t,检验n是不是合数
LL ret = pow_mod(a,x,n);
if(ret==n-1 || ret==1) return 0;
for(int i = 1; i < t; i++) {
ret = multi_mod(ret,ret,n);
if(ret == 1) return 1;
if(ret == n-1) return 0;
}
return 1;
}
bool Miller_Rabin(LL n) {
LL x = n - 1,t = 0;
while(!(x&1)) x >>=1,t++;
bool flag = 1;
if(t>=1) {
for(int k = 0; k < S; k++) {
LL a = rand()%(n-1) + 1;
if(check(a,n,t)) {
flag = 1; break;
}
flag = 0;
}
}
if(!flag || n==2) return 0;
return 1;
}
LL gcd(LL a,LL b) {
if (a==0) return 1;
if (a<0) return gcd(-a,b);
while (b){
LL t=a%b; a=b; b=t;
}
return a;
}
LL Pollard_rho(LL x,LL c) {
LL i=1,x0=rand()%x,y=x0,k=2;
while (1){
i++;
x0=(multi_mod(x0,x0,x)+c)%x;
LL d=gcd(y-x0,x);
if (d!=1 && d!=x){
return d;
}
if (y==x0) return x;
if (i==k){
y=x0;
k+=k;
}
}
}
void findfac(LL n) { //递归进行质因数分解N
if (!Miller_Rabin(n)){
factor[tot++] = n;
return;
}
LL p=n;
while (p>=n) p=Pollard_rho(p,rand() % (n-1) +1);
findfac(p);
findfac(n/p);
}
int main() {
//freopen("input.txt","r",stdin);
srand(time(NULL));
int T; cin >> T;
while(T--) {
LL n; cin >> n;
if(!Miller_Rabin(n)) {
puts("Prime"); continue;
}
tot = 0;
findfac(n);
LL ans = factor[0];
for(int i = 1; i < tot; i++) if(factor[i]<ans) ans = factor[i];
cout << ans << endl;
}
return 0;
}
??
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- spring – @Service类中的@Value属性为Null
- golang讲解(go语言)标准库分析之strings
- delphi – Datasnap xe vs Remobjects DataAbstract
- 如何在Pod和perldoc中使用Unicode字符?
- 解决EditorLineEnds.ttr被锁定导致Delphi2006-2010无法启动
- lua学习笔记---注释,变量,字符串
- Lua 脚本语言 与 C的互相调用
- vb.net中的“和”还是“AndAlso”与linq有关系吗?
- Delphi XE5 for Android 启动无黑屏等待总结
- Delphi Rest.JSON JsonToObject仅适用于f变量
