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
  • 相关阅读:
    Java对象的生命周期与作用域的讨论(转)
    [置顶] Oracle学习路线与方法
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
  • 原文地址:https://www.cnblogs.com/rausen/p/4512167.html
Copyright © 2011-2022 走看看