• [POJ 3243]Clever Y


    Description

    Little Y finds there is a very interesting formula in mathematics:

    XY mod Z = K

    Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?

    Input

    Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 109).
    Input file ends with 3 zeros separated by spaces.

    Output

    For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

    Sample Input

    5 58 33
    2 4 3
    0 0 0
    

    Sample Output

    9
    No Solution

    题解

    扩展BSGS:

    当模数 $c$ 不是质数的时候,显然不能直接使用 $BSGS$ 了,考虑它的扩展算法。

    前提:同余性质。

    令 $d = gcd(a, c)$ , $A = a cdot d,B = b cdot d, C = c cdot d$

    则 $a cdot d equiv b cdot d pmod{c cdot d}$

    等价于 $a equiv b pmod{c}$

    因此我们可以先消除因子。

    对于现在的问题 $(A cdot d)^x equiv B cdot d pmod{C cdot d}$ 当我们提出 $d = gcd(a, c)$ ($d eq 1$)后,原式化为 $A cdot (A cdot d)^{x-1} equiv B pmod{C}$ 。

    即求 $D cdot A^{x-cnt} equiv B pmod{C}$ ,令 $x = i cdot r-j+cnt$ 。之后的做法就和 $BSGS$ 一样了。

    值得注意的是因为这样求出来的解 $x geq cnt$ 的,但有可能存在解 $x < cnt$ ,所以一开始需要特判。

      1 //It is made by Awson on 2018.1.15
      2 #include <set>
      3 #include <map>
      4 #include <cmath>
      5 #include <ctime>
      6 #include <queue>
      7 #include <stack>
      8 #include <cstdio>
      9 #include <string>
     10 #include <vector>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <algorithm>
     15 #define LL long long
     16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
     17 #define Max(a, b) ((a) > (b) ? (a) : (b))
     18 #define Min(a, b) ((a) < (b) ? (a) : (b))
     19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
     20 using namespace std;
     21 const LL MOD = 233333;
     22 void read(LL &x) {
     23     char ch; bool flag = 0;
     24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
     25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
     26     x *= 1-2*flag;
     27 }
     28 void write(LL x) {
     29     if (x > 9) write(x/10);
     30     putchar(x%10+48);
     31 }
     32 
     33 LL a, b, c, ans;
     34 struct MAP {
     35     LL ha[MOD+5]; int id[MOD+5];
     36     void clear() {for (int i = 0; i < MOD; i++) ha[i] = id[i] = -1; }
     37     int count(LL x) {
     38     LL pos = x%MOD;
     39     while (true) {
     40         if (ha[pos] == -1) return 0;
     41         if (ha[pos] == x) return 1;
     42         ++pos; if (pos >= MOD) pos -= MOD;
     43     }
     44     }
     45     void insert(LL x, int idex) {
     46     LL pos = x%MOD;
     47     while (true) {
     48         if (ha[pos] == -1 || ha[pos] == x) {ha[pos] = x, id[pos] = idex; return; }
     49         ++pos; if (pos >= MOD) pos -= MOD;
     50     }
     51     }
     52     int query(LL x) {
     53     LL pos = x%MOD;
     54     while (true) {
     55         if (ha[pos] == x) return id[pos];
     56         ++pos; if (pos >= MOD) pos -= MOD;
     57     }
     58     }
     59 }mp;
     60 
     61 LL quick_pow(LL a, LL b, LL c) {
     62     LL ans = 1;
     63     while (b) {
     64     if (b&1) ans = ans*a%c;
     65     a = a*a%c, b >>= 1;
     66     }
     67     return ans;
     68 }
     69 LL gcd(LL a, LL b) {return b ? gcd(b, a%b) : a; }
     70 LL exBSGS(LL a, LL b, LL c) {
     71     if (b == 1) return 0;
     72     LL cnt = 0, d = 1, t;
     73     while ((t = gcd(a, c)) != 1) {
     74     if (b%t) return -1;
     75     ++cnt, b /= t, c /= t, d = d*(a/t)%c;
     76     if (d == b) return cnt;
     77     }
     78     mp.clear();
     79     LL tim = ceil(sqrt(c)), tmp = b%c;
     80     for (int i = 0; i <= tim; i++) {
     81     mp.insert(tmp, i); tmp = tmp*a%c;
     82     }
     83     t = tmp = quick_pow(a, tim, c); tmp = (tmp*d)%c;
     84     for (int i = 1; i <= tim; i++) {
     85     if (mp.count(tmp)) return tim*i-mp.query(tmp)+cnt;
     86     tmp = tmp*t%c;
     87     }
     88     return -1;
     89 }
     90 void work() {
     91     while ((~scanf("%lld%lld%lld", &a, &c, &b))) {
     92     if (c == 0) return;
     93     if ((ans = exBSGS(a%c, b%c, c)) == -1) printf("No Solution
    ");
     94     else write(ans), putchar('
    ');
     95     }
     96 }
     97 int main() {
     98     work();
     99     return 0;
    100 }
  • 相关阅读:
    遇到的两个问题
    项目分析(map复习)
    while小问题
    二级指针
    映射文件实现进程通信
    struct {0}初始化
    用boost共享内存实现进程通信的例子
    mongo二维数组操作
    项目分析(channelid是如果产生的)
    string为什么可以写入共享内存
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8294767.html
Copyright © 2020-2023  润新知