pub fn lcm(a: u64, b: u64) -> u64
Examples found in repository?
crates/competitive/src/math/discrete_logarithm.rs (line 413)
379fn discrete_logarithm_prime_power(a: u64, b: u64, p: u64, e: u32) -> Option<(u64, u64)> {
380 assert_ne!(p, 0);
381 assert_ne!(e, 0);
382 let n = p.pow(e);
383 assert!(a < n);
384 assert!(b < n);
385 assert_eq!(gcd(a, p), 1);
386 if p == 1 {
387 return Some((0, 1));
388 }
389 if a == 0 {
390 return if b == 0 { Some((1, 1)) } else { None };
391 }
392 if b == 0 {
393 return None;
394 }
395 if e == 1 {
396 return IC.with(|ic| unsafe { &mut *ic.get() }.discrete_logarithm(a, b, p));
397 }
398 let br = BarrettReduction::<u128>::new(n as _);
399 if p == 2 {
400 if e >= 3 {
401 if a % 4 == 1 && b % 4 != 1 {
402 return None;
403 }
404 let aa = if a % 4 == 1 { a } else { n - a };
405 let bb = if b % 4 == 1 { b } else { n - b };
406 let g = 5;
407 let ord = n / 4;
408 let x = pohlig_hellman_prime_power_order(g, aa, n, p, e - 2)?;
409 let y = pohlig_hellman_prime_power_order(g, bb, n, p, e - 2)?;
410 let t = solve_linear_congruence(x, y, ord)?;
411 match (a % 4 == 1, b % 4 == 1) {
412 (true, true) => Some(t),
413 (false, true) if t.0 % 2 == 0 => Some((t.0, lcm(t.1, 2))),
414 (false, false) if t.0 % 2 == 1 => Some((t.0, lcm(t.1, 2))),
415 (false, false) if a == b => Some((1, lcm(t.1, 2))),
416 _ => None,
417 }
418 } else if a == 1 {
419 if b == 1 { Some((0, 1)) } else { None }
420 } else {
421 assert_eq!(a, 3);
422 if b == 1 {
423 Some((0, 2))
424 } else if b == 3 {
425 Some((1, 2))
426 } else {
427 None
428 }
429 }
430 } else {
431 let ord = n - n / p;
432 let pf_ord = prime_factors(ord);
433 let g = (2..)
434 .find(|&g| check_primitive_root(g, ord, &br, &pf_ord))
435 .unwrap();
436 let mut pf_p = prime_factors(p - 1);
437 pf_p.push((p, e - 1));
438 let mut abm = vec![];
439 for (q, c) in pf_p {
440 let m = q.pow(c);
441 let d = ord / m;
442 let gg = pow(g, d, &br);
443 let aa = pow(a, d, &br);
444 let bb = pow(b, d, &br);
445 let x = pohlig_hellman_prime_power_order(gg, aa, n, q, c)?;
446 let y = pohlig_hellman_prime_power_order(gg, bb, n, q, c)?;
447 abm.push((x, y, m));
448 }
449 solve_linear_congruences(abm)
450 }
451}