Description

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

XY mod Z = K

Given XYZ, we all know how to figure out K fast. However, given XZK, 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 XZK (0 ≤ XZK ≤ 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.
 
题目大意:求离散对数。没有保证Z一定是素数。
PS:说一下上面没有提到的一个东西,最后一个O(sqrt(m))的循环中,逆元是没有必要每次都求的,可以预先求出来,让算法复杂度降至O(sqrt(m))。
在我的代码中,v = k^(-1) * a^(-i*m),可以在前面先求出k^(-1)和a^(-m),然后每次v都乘以a^(-m),而不需要每次对k*a^(i*m)求逆元。
 
代码(63MS):
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL; const int SIZEH = ; struct hash_map {
int head[SIZEH], size;
int next[SIZEH];
LL state[SIZEH], val[SIZEH]; void init() {
memset(head, -, sizeof(head));
size = ;
} void insert(LL st, LL sv) {
LL h = st % SIZEH;
for(int p = head[h]; ~p; p = next[p])
if(state[p] == st) return ;
state[size] = st; val[size] = sv;
next[size] = head[h]; head[h] = size++;
} LL find(LL st) {
LL h = st % SIZEH;
for(int p = head[h]; ~p; p = next[p])
if(state[p] == st) return val[p];
return -;
}
} hashmap; void exgcd(LL a, LL b, LL &x, LL &y) {
if(!b) x = , y = ;
else {
exgcd(b, a % b, y, x);
y -= x * (a / b);
}
} LL inv(LL a, LL n) {
LL x, y;
exgcd(a, n, x, y);
return (x + n) % n;
} LL pow_mod(LL x, LL p, LL n) {
LL ret = ;
while(p) {
if(p & ) ret = (ret * x) % n;
x = (x * x) % n;
p >>= ;
}
return ret;
} LL BabyStep_GiantStep(LL a, LL b, LL n) {
for(LL i = , e = ; i <= ; ++i) {
if(e == b) return i;
e = (e * a) % n;
}
LL k = , cnt = ;
while(true) {
LL t = __gcd(a, n);
if(t == ) break;
if(b % t != ) return -;
n /= t; b /= t; k = (k * a / t) % n;
++cnt;
}
hashmap.init();
hashmap.insert(, );
LL e = , m = LL(ceil(sqrt(n + 0.5)));
for(int i = ; i < m; ++i) {
e = (e * a) % n;
hashmap.insert(e, i);
}
LL p = inv(pow_mod(a, m, n), n), v = inv(k, n);
for(int i = ; i < m; ++i) {
LL t = hashmap.find((b * v) % n);
if(t != -) return i * m + t + cnt;
v = (v * p) % n;
}
return -;
} int main() {
LL x, z, k;
while(cin>>x>>z>>k) {
if(x == && z == && k == ) break;
LL ans = BabyStep_GiantStep(x % z, k % z, z);
if(ans == -) puts("No Solution");
else cout<<ans<<endl;
}
}

POJ 3243 Clever Y(离散对数-拓展小步大步算法)的更多相关文章

  1. POJ 3243 Clever Y (求解高次同余方程A^x=B(mod C) Baby Step Giant Step算法)

    不理解Baby Step Giant Step算法,请戳: http://www.cnblogs.com/chenxiwenruo/p/3554885.html #include <iostre ...

  2. POJ 3243 Clever Y 扩展BSGS

    http://poj.org/problem?id=3243 这道题的输入数据输入后需要将a和b都%p https://blog.csdn.net/zzkksunboy/article/details ...

  3. poj 3243 Clever Y && 1467: Pku3243 clever Y【扩展BSGS】

    扩展BSGS的板子 对于gcd(a,p)>1的情况 即扩展BSGS 把式子变成等式的形式: \( a^x+yp=b \) 设 \( g=gcd(a,p) \) 那么两边同时除以g就会变成: \( ...

  4. poj 3243 Clever Y 高次方程

    1 Accepted 8508K 579MS C++ 2237B/** hash的强大,,还是高次方程,不过要求n不一定是素数 **/ #include <iostream> #inclu ...

  5. [POJ 3243]Clever Y

    Description Little Y finds there is a very interesting formula in mathematics: XY mod Z = K Given X, ...

  6. POJ 3243 Clever Y | BSGS算法完全版

    题目: 给你A,B,K 求最小的x满足Ax=B (mod K) 题解: 如果A,C互质请参考上一篇博客 将 Ax≡B(mod C) 看作是Ax+Cy=B方便叙述与处理. 我们将方程一直除去A,C的最大 ...

  7. POJ 3243 Clever Y Extended-Baby-Step-Giant-Step

    题目大意:给定A,B,C,求最小的非负整数x,使A^x==B(%C) 传说中的EXBSGS算法0.0 卡了一天没看懂 最后硬扒各大神犇的代码才略微弄懂点0.0 參考资料: http://quarter ...

  8. 【POJ】3243 Clever Y

    http://poj.org/problem?id=3243 题意:求$a^y \equiv b \pmod{p}$最小的$y$.(0<=x, y, p<=10^9) #include & ...

  9. POJ 2417 Discrete Logging(离散对数-小步大步算法)

    Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 ...

随机推荐

  1. linux 不能用clock 计算sleep的时间

    http://bbs.csdn.net/topics/390558707 在Windows Sleep()占用processor time,Linux下的sleep()不占用processor tim ...

  2. Ubuntu 14.04 LTS 64bit 编译SDL的问题

    http://blog.csdn.net/jhting/article/details/38523945 Ubuntu 14.04 LTS 64bit 编译SDL的问题 分类: C/C++2014-0 ...

  3. ADO.NET实体数据模型使用探索1

    今天研究了下ADO.NET实体数据模型,想写个关于两张有外键关系的增改删查,以此来稍增加点难度. 编程环境:vs2010+sql2005 1.在SQL2005下建立三张表:学生信息表Student(S ...

  4. 设计模式:享元模式(Flyweight)

    定   义:运用共享技术有效地支持大量细粒度的对象. 结构图: 内部状态:在享元对象内部并且不会随环境而改变的共享部分. 外部状态:随环境改变而改变的.不可共享的状态. Flyweight类,具体享元 ...

  5. 1006 最长公共子序列Lcs

    1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...

  6. [LeetCode]题解(python):112 Path Sum

    题目来源 https://leetcode.com/problems/path-sum/ Given a binary tree and a sum, determine if the tree ha ...

  7. 模糊搜索UISearchBar

    #import "Search_ViewController.h" @interface Search_ViewController ()<UITableViewDataSo ...

  8. Windows-007-进程相关命令(netstat、tasklist、taskkill、tskill)实战实例图文详解

    本节主要讲述 Windows 系统下,nestat.tasklist.tskill 三个 CMD 命令的参数,及使用方法:以及如何利用三者结合查看进程信息和结束进程.敬请亲们参阅,希望能对亲们有所帮助 ...

  9. JavaScript实现在页面上的文本框中输入小写字母自动变为大写字母

    <script language="javascript" type="text/javascript"> $(function () { $(&q ...

  10. Tuning SQL via case when statement

    原SQL如下:SQL的主要问题是红色部分居然通过标量查询,反复的查找与SQL相同的基表,很显然这个可以用case when来简化. select a.TRAN_ID,a.AMOUNT,a.BALANC ...