POJ2429 GCD & LCM Inverse pollard_rho大整数分解
Input
Output
Sample Input
3 60
Sample Output
12 15
题意:给出两个数的最大公约数和最小公倍数,让你找出满足条件的两个数,使他们的和最小。
题解:
对于两个数a,b和他们的最大公约数gcd以及最小公倍数lcm,有lcm=a*b/gcd,进一步变形可以得到:(a/gcd * b/gcd)*gcd=lcm,即(a/gcd * b/gcd)=lcm/gcd,我们令m=a/gcd,n=b/gcd,那么问题就变为了:找出两个互素的整数,使他们的乘积为key=lcm/gcd。我们可以用Pollard_rho算法进行质因素分解的方法找出lcm/gcd的所有素因子,然后dfs找出任意几个素数因子之积(设为x),设y=key/x,找出最小的x+y就行了
代码:
1 #include <cstdio>
2
3 #include <iostream>
4
5 #include <cstdlib>
6
7 #include <cmath>
8
9 #include <algorithm>
10
11
12
13 #define times 10
14
15 #define N 501
16
17 using namespace std;
18
19 typedef unsigned long long LL;
20
21 const LL INF=(LL)1<<61;
22
23 LL key,ct,cnt,gd,lm,resa,resb,mini;
24
25 LL fac[N],num[N];
26
27
28
29 LL gcd(LL a,LL b)
30
31 {
32
33 return b?gcd(b,a%b):a;
34
35 }
36
37
38
39 LL multi(LL a,LL b,LL m)
40
41 {
42
43 LL ans=0;
44
45 a%=m;
46
47 while(b)
48
49 {
50
51 if(b&1)
52
53 {
54
55 ans=(ans+a)%m;
56
57 b--;
58
59 }
60
61 b>>=1;
62
63 a=(a+a)%m;
64
65 }
66
67 return ans;
68
69 }
70
71
72
73 LL quick_mod(LL a,LL b,LL m)
74
75 {
76
77 LL ans=1;
78
79 a%=m;
80
81 while(b)
82
83 {
84
85 if(b&1)
86
87 {
88
89 ans=multi(ans,a,m);
90
91 b--;
92
93 }
94
95 b>>=1;
96
97 a=multi(a,a,m);
98
99 }
100
101 return ans;
102
103 }
104
105
106
107 bool Miller_Rabin(LL n)
108
109 {
110
111 if(n==2) return true;
112
113 if(n<2||!(n&1)) return false;
114
115 LL m=n-1;
116
117 int k=0;
118
119 while(!(m&1))
120
121 {
122
123 k++;
124
125 m>>=1;
126
127 }
128
129 for(int i=0;i<times;i++)
130
131 {
132
133 LL a=rand()%(n-1)+1;
134
135 LL x=quick_mod(a,m,n);
136
137 LL y=0;
138
139 for(int j=0;j<k;j++)
140
141 {
142
143 y=multi(x,x,n);
144
145 if(y==1&&x!=1&&x!=n-1) return false;
146
147 x=y;
148
149 }
150
151 if(y!=1) return false;
152
153 }
154
155 return true;
156
157 }
158
159
160
161 LL Pollard_rho(LL n,LL c)
162
163 {
164
165 LL i=1,k=2;
166
167 LL x=rand()%(n-1)+1;
168
169 LL y=x;
170
171 while(true)
172
173 {
174
175 i++;
176
177 x=(multi(x,x,n)+c)%n;
178
179 LL d=gcd((y-x+n)%n,n);
180
181 if(1<d&&d<n) return d;
182
183 if(y==x) return n;
184
185 if(i==k)
186
187 {
188
189 y=x;
190
191 k<<=1;
192
193 }
194
195 }
196
197 }
198
199
200
201 void Find(LL n,LL c)
202
203 {
204
205 if(n==1) return ;
206
207 if(Miller_Rabin(n))
208
209 {
210
211 fac[ct++]=n;
212
213 return ;
214
215 }
216
217 LL p=n;
218
219 LL k=c;
220
221 while(p>=n) p=Pollard_rho(p,c--);
222
223 Find(p,k);
224
225 Find(n/p,k);
226
227 }
228
229
230
231 void dfs(LL dept,LL product)
232
233 {//dept为递归深度,product为其中一个因子
234
235 if(dept==cnt)
236
237 {
238
239 LL a=product;
240
241 LL b=key/a;
242
243 if(gcd(a,b)==1)
244
245 {
246
247 a*=gd;
248
249 b*=gd;
250
251 if(a+b<mini)
252
253 {
254
255 mini=a+b;
256
257 resa=a;
258
259 resb=b;
260
261 }
262
263 }
264
265 return ;
266
267 }
268
269 for(int i=0;i<=num[dept];i++)
270
271 {
272
273 if(product>mini) return ;
274
275 dfs(dept+1,product);
276
277 product*=fac[dept];
278
279 }
280
281 }
282
283
284
285
286
287 void Solve(LL n)
288
289 {
290
291 ct=0;
292
293 Find(n,120);
294
295 sort(fac,fac+ct);
296
297 num[0]=1;
298
299 int k=1;
300
301 for(int i=1;i<ct;i++)
302
303 {
304
305 if(fac[i]==fac[i-1])
306
307 num[k-1]++;
308
309 else
310
311 {
312
313 num[k]=1;
314
315 fac[k++]=fac[i];
316
317 }
318
319 }
320
321 cnt=k;
322
323 dfs(0,1);
324
325 if(resa>resb) swap(resa,resb);
326
327 }
328
329
330
331 int main()
332
333 {
334
335 while(cin>>gd>>lm)
336
337 {
338
339 if(gd==lm)
340
341 {
342
343 printf("%llu %llu\n",gd,lm);
344
345 continue;
346
347 }
348
349 mini=INF;
350
351 key=lm/gd;
352
353 Solve(key);
354
355 printf("%llu %llu\n",resa,resb);
356
357 }
358
359 return 0;
360
361 }
POJ2429 GCD & LCM Inverse pollard_rho大整数分解的更多相关文章
- POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)
题目大意 给定两个数a,b的GCD和LCM,要求你求出a+b最小的a,b 题解 GCD(a,b)=G GCD(a/G,b/G)=1 LCM(a/G,b/G)=a/G*b/G=a*b/G^2=L/G 这 ...
- 【Pollard-rho算法】【DFS】poj2429 GCD & LCM Inverse
题意:给你一两个数m和n,它们分别是某对数A,B的gcd和lcm,让你求出一对使得A+B最小的A,B. n/m的所有质因子中,一定有一部分是只在A中的,另一部分是只在B中的. 于是对n/m质因子分解后 ...
- poj2429 GCD & LCM Inverse
用miller_rabin 和 pollard_rho对大数因式分解,再用dfs寻找答案即可. http://poj.org/problem?id=2429 #include <cstdio&g ...
- POJ 1811 Prime Test (Pollard rho 大整数分解)
题意:给出一个N,若N为素数,输出Prime.若为合数,输出最小的素因子.思路:Pollard rho大整数分解,模板题 #include <iostream> #include < ...
- [POJ 2429] GCD & LCM Inverse
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10621 Accepted: ...
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
- POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)
题意:给出a和b的gcd和lcm,让你求a和b.按升序输出a和b.若有多组满足条件的a和b,那么输出a+b最小的.思路:lcm=a*b/gcd lcm/gcd=a/gcd*b/gcd 可知a/gc ...
- POJ 2429 GCD & LCM Inverse(Pollard_Rho+dfs)
[题目链接] http://poj.org/problem?id=2429 [题目大意] 给出最大公约数和最小公倍数,满足要求的x和y,且x+y最小 [题解] 我们发现,(x/gcd)*(y/gcd) ...
- 整数(质因子)分解(Pollard rho大整数分解)
整数分解,又称质因子分解.在数学中,整数分解问题是指:给出一个正整数,将其写成几个素数的乘积的形式. (每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数.) .试除法(适用于范 ...
随机推荐
- 🎉 Element UI for Vue 3.0 来了!
第一个使用 TypeScript + Vue 3.0 Composition API 重构的组件库 Element Plus 发布了 ~ 2016 年 3 月 13 日 Element 悄然诞生,经历 ...
- Linux 中软链接和硬链接的使用
Linux 链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link). 硬链接和软链接 硬链接 --- ln 要链接的文件 新硬链接名 软连接 --- l ...
- (十三)利用BASE_DIR来import模板
实际工程的组织架构一般是这样的: bin包下的bin.py是实际的执行文件,my_mould包下的是业务逻辑的实现模板 bin.py需要import my_mould下的py文件,而bin和my_mo ...
- 【Oracle】B-tree和函数索引
转自:https://www.cnblogs.com/yumiko/p/5957613.html 函数索引 1.1 概述 在实际应用中,当条件列使用函数运算进行数据匹配时,即使该列建立了索引,索引也不 ...
- Trino总结
文章目录 1.Trino与Spark SQL的区别分析 2.Trino与Spark SQL解析过程对比 3.Trino基本概念 4.Trino架构 5.Trino SQL执行流程 6.Trino Ta ...
- 安装OpenDaylight及Openflow插件
1. 安装 Java 和 Maven CentOS7: yum install java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64 ma ...
- /bin/sh: cc: command not found
make的时候报错:/bin/sh: cc: command not found 解决: 1. sudo yum -y install gcc gcc-c++ libstdc++-devel 2. m ...
- 并发编程:Actors 模型和 CSP 模型
https://mp.weixin.qq.com/s/emB99CtEVXS4p6tRjJ2xww 并发编程:Actors 模型和 CSP 模型 ImportNew 2017-04-27
- Python新手入门值流程结构
if-else socore =int(input('请输入成绩')); if socore>=90 : print("A") elif socore>=80 : pr ...
- luogu p3369
题目描述您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数删除x数(若有多个相同的数,因只删除一个)查询x数的排名(排名定义为比当前数小的数的个数+1.若有多个相同 ...