POJ 2191 各种素数算法
2012-02-23 20:42
281 查看
来自Discuss. 分析:首先打出63以内的素数prime[i...n],之后利用miller_rabin素数测试法测试 2^prime[i]-1是否为素数(可打表或不,不怎么影响)。如果不是则利用Pollard对该数进行质因子分解。 对于miller_rabin素数测试法和Pollard整数质因子分解数论方面的书都有, 几乎是模板。 code: 2191 Accepted 172K 16MS C++ 3050B #include<iostream> #include<cstring> #include<ctime> #include<cstdlib> #include<cmath> #include<algorithm> //#define MAX (pow(2.0, 62)) #define C 240 #define TIME 6 using namespace std; __int64 ans[65]; //存2^prime[i]-1非素数的质因子 int prime[65],x[65],m,cnt; __int64 gcd(__int64 a,__int64 b) { if(b==0) return a; return gcd(b,a%b); } __int64 mod_mult(__int64 a,__int64 b,__int64 n) { __int64 s=0; a=a%n; while(b) { if (b&1) { s+=a; if(s>=n) s-=n; } a=a<<1; if(a>=n) a-=n; b=b>>1; } return s; } __int64 mod_exp(__int64 a, __int64 b,__int64 n) { __int64 d=1; a=a%n; while (b>=1) { if (b&1) d=mod_mult(d,a,n); a=mod_mult(a,a,n); b=b>> 1; } return d; } bool Wintess(__int64 a,__int64 n) { __int64 m,x,y; int i,j=0; m=n-1; while(m%2==0) { m=m>>1; j++; } x=mod_exp(a, m, n); for(i=1;i<=j;i++) { y=mod_exp(x,2,n); if((y==1)&&(x!=1)&&(x!=n-1)) return true; x=y; } if (y!=1) return true; return false; } bool miller_rabin(int times,__int64 n) { __int64 a; int i; if (n==1) return false; if (n==2) return true; if (n%2==0) return false; srand(time(NULL)); for (i =1;i<=times;i++) { a=rand()%(n-1)+1; if(Wintess(a,n)) return false; } return true; } __int64 Pollard(__int64 n,int c) { __int64 i,k,x,y,d; srand(time(NULL)); i=1; k=2; x=rand()%n; y=x; while(true) { i++; x=(mod_mult(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 get_prime(__int64 n,int c) {//二分找出所有素因子 __int64 m; if(n==1) return; if(miller_rabin(TIME,n)) { ans[cnt++]=n; return; } m=n; while(m>=n) m=Pollard(m,c--); get_prime(m,c); get_prime(n/m,c); } void init() { int i,tmp; memset(x,0,sizeof(x)); x[0]=x[1]=1; m=0; for(i=2;i<=63;i++) { if(!x[i]) { prime[++m]=i; tmp=i*i; while(tmp<=63) { x[tmp]=1; tmp+=i; } } } } bool cmp(__int64 n1,__int64 n2) { return n1<n2; } int main() { init(); int p,i,j; scanf("%d",&p); for(i=1;i<=m;i++) { if(prime[i]<=p) { __int64 n=((__int64)1<<prime[i])-1; if(miller_rabin(TIME,n))//判断是否是素数 continue; memset(ans,0,sizeof(ans)); cnt=0; get_prime(n,C); //分解素因子 sort(ans,ans+cnt,cmp); for(j=0;j<cnt-1;j++) printf("%I64d * ",ans[j]); printf("%I64d = %I64d = ( 2 ^ %d ) - 1\n",ans[j],n,prime[i]); } else break; } return 0; }
相关文章推荐
- 网络流最经典的入门题 各种网络流算法都能AC。 poj 1273 Drainage Ditches
- poj 2191 大数素数判定 && 大数素数分解
- poj 2191 Mersenne Composite Numbers 筛法判素数
- 各种高性能算法 求素数 太牛 挑战算法
- 打印素数的各种算法
- poj2253 Frogger(各种图论基础算法都能搞)&&poj1797 Heavy Transportation
- POJ 2191 梅森素数
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
- poj 2421-Constructing Roads(经典Prime算法)
- 数据结构C#实现-二叉查找树的创建,查找,以及各种递归(非递归)遍历算法
- 算法大全--各种理解 2014-01-16 21:34 135人阅读 评论(0) 收藏
- poj 3041 Asteroids(二分图匹配匈牙利算法)
- poj_3164 Command Network(最小树形图+朱刘算法)
- Mayor's posters OpenJ_Bailian -POJ - 2528 (离散化算法)
- 数据挖掘——各种分类算法的优缺点
- POJ 2243 A* 算法
- POJ 2689 Prime Distance 素数筛选法应用
- 素数推断算法(高效率)
- for循环各种算法效率
- 算法学习之旅,初级篇(14)--素数的个数