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. EF的表连接方法Include()

    在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...

  2. Linq&Lumbda (2)

    "Lambda表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型. Lambda 运算符: => 该运算符读为"goes to&quo ...

  3. 比较setImmediate(func),setTimeout(func),process.nextTick(func)

    node中的事件优先级机制: console.log('第一笔!'); process.nextTick(function() { console.log('吃个饭吧!'); setImmediata ...

  4. git warning解决方案

    1.warning: LF will be replaced by CRLF in xxxxx. 设置: git config core.autocrlf false

  5. 简单的form表单

    效果 html <ul class="edit_list"> <li><em>*</em><span class=" ...

  6. ArcGIS API for Silverlight中加载Google地形图(瓦片图)

    原文:ArcGIS API for Silverlight中加载Google地形图(瓦片图) 在做水利.气象.土地等行业中,若能使用到Google的地形图那是再合适不过了,下面就介绍如何在ArcGIS ...

  7. 2014年最大福利:185个Google排名因素!免费电子书下载

    本博开张以来最大规模的干货放送!新手老手都有用! 不要再去追求PR了,不要再去发博客发论坛发外链了! 关注真正有用的Google排名因素! 整整185项,每一项都附带说明,必要的地方会给出一些附加的阅 ...

  8. 【tips】判断两个整数是否是同一个数量级

    leetcode刷题的时候,需要用到,已知整数A,B,且A>B,判断AB是否是同一数量级的. 第一想到的是不停地除以10,得到每个数字的数量级再进行比较,太麻烦: 转而向转化成字符串比较,还是麻 ...

  9. 转载:XPath基本语法

    出处:http://www.cnblogs.com/Miko2012/archive/2012/10/26/2740840.html XPath的语法最基本的节点之间用/,属性用@,还有几个函数记住了 ...

  10. php常用转义字符‘ “ {} $ \n

    php 单引号和双引号的区别: 双引号串中的内容可以被解释而且替换,而单引号串中的内容总被认为是普通字符. <?php $a = 'abc'; echo "<br>&quo ...