标签:
通过poj1811整理这些算法的模板
所有代码如下:
1 #include <iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cstring>
5 using namespace std;
6 #define LL long long
7 const int maxs = 10000000+5;
8 //对于1要外加特判,否则会运行错误
9 //用小素数表做随机种子
10 __int64 pri[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
11 __int64 ans[maxs],flag;
12 //ans数组记录分解质因数的结果(没有顺序),flag记录质因数的个数,相同的质因数不合并!
13
14 //最大公约数
15 __int64 gcd(__int64 a,__int64 b)
16 {
17 while(b!=0)
18 {
19 __int64 r = a%b;
20 a=b;
21 b=r;
22 }
23 return a;
24 }
25 //乘法快速幂a*b%n,不写连乘是防止相乘时溢出
26 __int64 multi(__int64 a,__int64 b,__int64 n)
27 {
28 __int64 temp = 0;
29 while(b!=0)
30 {
31 if(b%2==1)
32 {
33 temp+=a;
34 if(temp>=n)
35 temp-=n;
36 }
37 a*=2;
38 if(a>=n)
39 a-=n;
40 b/=2;
41 }
42 return temp;
43 }
44 //乘方快速幂a^n%m
45 __int64 multimod(__int64 a,__int64 n,__int64 m)
46 {
47 __int64 ans=1;
48 while(n!=0)
49 {
50 if(n%2==1)
51 ans=multi(ans,a,m);
52 a=multi(a,a,m);
53 n/=2;
54 }
55 return ans;
56 }
57
58 //判断大数是否为素数(米勒罗宾算法)
59 //调用multimod(),multi()函数
60 bool miller_rabin(__int64 n)
61 {
62 if(n<2)
63 return false;
64 if(n==2)
65 return true;
66 if(n%2==0)
67 return false;
68 __int64 k = 0,m,a,i,j;
69 m=n-1;
70 while(m%2==0)
71 {
72 m=m/2;
73 k++;
74 }
75 for(i=0;i<10;i++)
76 {
77 if(pri[i]>=n)
78 return true;
79 a = multimod(pri[i],m,n);
80 if(a==1)
81 continue;
82 for(j=0;j<k;j++)
83 {
84 if(a==n-1)
85 break;
86 a = multi(a,a,n);
87 }
88 if(j==k)
89 return false;
90 }
91 return true;
92 }
93 //寻找因数
94 __int64 pollard_rho(__int64 c,__int64 n)
95 {
96 __int64 i,x,y,k,d;
97 i=1;
98 x = y = rand()%n;
99 k=2;
100 do
101 {
102 i++;
103 d = gcd(n+y-x,n);
104 if(d>1&&d<n)
105 return d;
106 if(i==k)
107 {
108 y=x;
109 k=k*2;
110 }
111 x = (multi(x,x,n)+n-c)%n;
112 }while(y!=x);
113 return n;
114 }
115 //递归分解,把大整数n分解保存到ans全局数组中,保存的是质因数
116 //且这些质因数没有保证顺序,也没有排重
117 void rhoAll(__int64 n)
118 {
119 if(miller_rabin(n))
120 {
121 ans[flag]=n;
122 flag++;
123 return;
124 }
125 __int64 t = n;
126 while(t>=n)
127 {
128 //随机取出一个因子,不一定是素数,也不确定大小
129 t = pollard_rho(rand()%(n-1)+1,n);
130 }
131 rhoAll(t);
132 rhoAll(n/t);
133 return;
134 }
135
136 //返回大整数n最小的质因数
137 __int64 rho(__int64 n)
138 {
139 if(miller_rabin(n))
140 return n;
141 __int64 t = n;
142 while(t>=n)
143 {
144 t = pollard_rho(rand()%(n-1)+1,n);
145 }
146 __int64 a = rho(t);
147 __int64 b = rho(n/t);
148 return a<b?a:b;
149 }
150 int main()
151 {
152 //freopen("in.txt","r",stdin);
153 int T;
154 scanf("%d",&T);
155 while(T--)
156 {
157 flag = 0;
158 __int64 n;
159 scanf("%I64d",&n);
160 if(miller_rabin(n))//是素数
161 printf("Prime\n");
162 else
163 {
164 rhoAll(n);//把大数n分解成质因数
165 printf("%I64d\n",rho(n));//最小的质因数
166 }
167 for(int i=0;i<flag;i++)//输出这些质因数
168 printf("%I64d\n",ans[i]);
169 }
170 return 0;
171 }
标签:
原文地址:http://www.cnblogs.com/wt20/p/5762601.html