DiscreteLog.cpp 616 B

1234567891011121314151617181920212223242526
  1. //return a^p (mod n)
  2. int pow_mod(int a, int p, int n){
  3. if (p == 0) return 1;
  4. int ans = pow_mod(a, p/2, n);
  5. ans = (ans*ans) % n;
  6. if (p % 2 == 1) ans = (ans*a) % n;
  7. return ans;
  8. }
  9. // Baby-Step-Giant-Step Algorithm. O(n^(0.5)*logn)
  10. // solve a^x = b (mod n). Return -1 for non solution
  11. int log_mod(int a, int b, int n) {
  12. int m, v, e = 1, i;
  13. m = (int) sqrt(n + 0.5);
  14. v = mod_inverse(pow_mod(a, m, n), n);
  15. map <int , int > x;
  16. x[1] = 0;
  17. for (i = 1; i < m; i++) {
  18. e = (e * a) % n;
  19. if (!x.count(e)) x[e] = i;
  20. }
  21. for (i = 0; i < m; i++){
  22. if (x.count(b)) return i*m + x[b];
  23. b = (b * v) % n;
  24. }
  25. return -1;
  26. }