zoukankan      html  css  js  c++  java
  • BZOJ2480 Spoj3105 Mod

    乍一看题面:$$a^x equiv b (mod m)$$

    是一道BSGS,但是很可惜$m$不是质数,而且$(m, a) ot= 1$,这个叫扩展BSGS【额......

    于是我们需要通过变换使得$(m, a) = 1$

    首先令$g = (a, m)$,则原式等价于:$$a ^ x + k * m = b, k in mathbb{Z}$$

    移项可得:$$frac{a} {g} * a ^ {x - 1} + k * frac {m} {g} = frac {b} {g}$$

    此时如果$b ot equiv 0 (mod g)$则无解

    令$m' = frac {m} {g}, b' = frac {b} {g} * (frac{a} {g}) ^ {-1}$

    于是得到新式:$$a ^ {x - 1} = b' (mod m')$$

    于是可以一直迭代到$(m, a) = 1$,然后用BSGS来计算答案即可

     1 /**************************************************************
     2     Problem: 2480
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:3256 ms
     7     Memory:1568 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12 #include <ext/pb_ds/assoc_container.hpp>
    13 #include <ext/pb_ds/hash_policy.hpp>
    14  
    15 using namespace std;
    16 using namespace std;
    17 typedef long long ll;
    18 typedef __gnu_pbds::cc_hash_table <int, int> hash;
    19  
    20 inline int read();
    21  
    22 int a, b, m, ans;
    23 hash h;
    24  
    25 inline int pow(ll x, ll y, ll mod) {
    26     static ll res;
    27     res = 1;
    28     while (y) {
    29         if (y & 1) res = res * x % mod;
    30         x = x * x % mod, y >>= 1;
    31     }
    32     return (int) res;
    33 }
    34  
    35 inline int BSGS(int a, int b, int p, ll now) {
    36     static int m, i;
    37     static ll base;
    38     m = (int) ceil(sqrt(p)), base = b;
    39     h.clear();
    40     for (i = 0; i < m; ++i)
    41         h[base] = i, base = base * a % p;
    42          
    43     base = pow(a, m, p);
    44     for (i = 1; i <= m + 1; ++i) {
    45         now = now * base % p;
    46         if (h.find(now) != h.end()) return i * m - h[now];
    47     }
    48     return -1;
    49 }
    50  
    51 int extend_BSGS(int a, int b, int m) {
    52     static int cnt, g, res;
    53     static ll t;
    54     a %= m, b %= m;
    55     if (b == 1) return 0;
    56     cnt = 0, g = __gcd(a, m), t = 1;
    57     while (g != 1) {
    58         if (b % g) return -1;
    59         m /= g, b /= g, t = t * a / g % m;
    60         ++cnt;
    61         if (b == t) return cnt;
    62         g = __gcd(a, m);
    63     }
    64     res = BSGS(a, b, m, t);
    65     return ~res ? res + cnt : res;
    66 }
    67  
    68 int main() {
    69     while (1) {
    70         a = read(), m = read(), b = read();
    71         if (!a && !m && !b) return 0;
    72         ans = extend_BSGS(a, b, m);
    73         if (!~ans) puts("No Solution");
    74         else printf("%d
    ", ans);
    75     }
    76     return 0;
    77 }
    78  
    79 inline int read() {
    80     static int x;
    81     static char ch;
    82     x = 0, ch = getchar();
    83     while (ch < '0' || '9' < ch)
    84         ch = getchar();
    85     while ('0' <= ch && ch <= '9') {
    86         x = x * 10 + ch - '0';
    87         ch = getchar();
    88     }
    89     return x;
    90 }
    View Code
  • 相关阅读:
    STL与泛型编程-练习2-GeekBand
    HashSet
    JAVA集合
    分布式锁1 Java常用技术方案
    JAVA 锁
    JAVA多线程二
    JAVA多线程一
    Redis pipeline and list
    mongo 安装
    Intersection of Two Arrays
  • 原文地址:https://www.cnblogs.com/rausen/p/4512167.html
Copyright © 2011-2022 走看看