Advertisement
Guest User

Baby-step Giant step

a guest
Feb 5th, 2011
743
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.75 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define INF 0xFFFFFFFU
  5.  
  6. typedef unsigned long long u64;
  7.  
  8. unsigned modexp(unsigned b, unsigned e, unsigned m) {
  9.     unsigned r;
  10.     for (r = 1; e > 0; e >>= 1) {
  11.         if (e & 1) r = (unsigned)(((u64)r * (u64)b) % (u64)m);
  12.         b = (unsigned)(((u64)b * (u64)b) % (u64)m);
  13.     }
  14.     return r;
  15. }
  16.  
  17. unsigned modmul(unsigned a, unsigned b, unsigned m) {
  18.     return (unsigned)(((u64)a * (u64)b) % (u64)m);
  19. }
  20.  
  21. int cmp(const void *p, const void *q) {
  22.     unsigned x = *(unsigned *)p, y = *(unsigned *)q;
  23.     return (x > y) ? 1 : ((x < y) ? -1 : 0);
  24. }
  25.  
  26. unsigned isqrt(unsigned a) {
  27.     unsigned x, y;
  28.     for (x = a; x > 1; x = y)
  29.         if ((y = (x + a / x) >> 1) >= x) break;
  30.     return x;
  31. }
  32.  
  33. int look(unsigned s[], int b, unsigned x) {
  34.     int a, c;
  35.     for (a = 0, b--; a <= b;) {
  36.         if (s[c = (a + b) >> 1] < x)
  37.             a = c + 1;
  38.         else if (s[c] > x)
  39.             b = c - 1;
  40.         else
  41.             return 1;
  42.     }
  43.     return 0;
  44. }
  45.  
  46. unsigned solve(unsigned a, unsigned b, unsigned m) {
  47.     static unsigned s[65536];
  48.     unsigned i, k, n, y;
  49.  
  50.     a %= m;
  51.     b %= m;
  52.  
  53.     n = isqrt(m);
  54.     if (n * n < m) n++;
  55.  
  56.     if (b == 1) return 0;
  57.  
  58. /* a^x = b (mod m)
  59.    x = ny-z, n=ceil(sqrt(m)), 1<=y<=n, 0<=z<n.
  60.    (a^n)^y = b a^z (mod m)
  61. */
  62.     for (s[0] = b, i = 1; i < n; i++)
  63.         s[i] = modmul(s[i-1], a, m);
  64.     qsort(s, n, sizeof(s[0]), &cmp);
  65.  
  66.     k = modexp(a, n, m);
  67.     for (y = 1, i = 1; y <= n; y++) {
  68.         i = modmul(i, k, m);
  69.         if (look(s, n, i)) break;
  70.     }
  71.  
  72.     if (y > n) return INF;
  73.  
  74.     y = n * (y - 1);
  75.     k = modexp(a, y, m);
  76.  
  77.     while (k != b) {
  78.         k = modmul(k, a, m);
  79.         y++;
  80.     }
  81.  
  82.     return y;
  83. }
  84.  
  85. int main() {
  86.     unsigned a, b, m, r;
  87.     while (scanf("%u %u %u", &m, &a, &b) == 3) {
  88.         if ((r = solve(a, b, m)) == INF)
  89.             printf("no solution\n");
  90.         else
  91.             printf("%u\n", r);
  92.     }
  93.     return 0;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement