题目 : http://acm.hdu.edu.cn/showproblem.php?pid=2815
题目大意 : 求解 a ^ x = b ( mod c)
算法 : 扩展小步大步攻击(AC大牛)
思路 :在介绍扩展小步大步攻击之前, 先说两个要点
1 :如 d = a % b, 则 Gcd(a, b) | d;
证明 : d = a % b = a – a / b * b = ged(a, b) [a / gcd(a, b)
2 :消因子
对于 a ^ x = b ( mod c)
可写成 a ^ x = k * c + b
设 g1 = gcd(a, c), 若有解着必有 g1 | b
方程两边同时消去g得
再设g2 = gcd(a, c’), 同理,若有解, 则 g2 | b’
方程两边同时消去g得
同样的操作, 假设第n次后a, c不具有因子, 即a, c’’’’’’’ 互素时
则有 a/g(n) * a/g(n-1)……*a/g1 * a^(x – n) = b’’’’’(n) (mod c’’’’’(n))
令 d = a/g(n) * a/g(n-1)……*a/g1,
则有 d * a (x - n) = B (mod C);
这样, a 与 C 就是互素的了
//
扩展小步大步攻击:a ^ x = b (mod c)
1 :
2 :
3 : m = ceil (sqrt(C))
4 : 将 a ^ (x - n) 化为
5 : for j = 0 -> m
6 : for i = 0 -> m
7 : AA * x = B (mod C) ext_gcd求解x,判断hash中是否有 x若有, 则答案为I * m + j + n
/
消因子的目的在于将AA与C化为互素的关系, 这样用ext_gcd求的x时就只有唯一解了。
而消因子后, 我们的解最小为n,如果小于n有解, 则会出现错误, 故有了第一步的操作,先看n以前是否有满足的解,100就足够了
//介意与ac大牛原著一起看http://hi.baidu.com/aekdycoin/blog/item/b317ca18bb24334942a9ad55
提交情况 :runtime error 5 次
感想和经验颇多, 都在思路理了
AC code
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAXN 65536
#define I64 __int64
struct LINK{
}HASH_LINK[1000000];
I64 ad, head[MAXN];
I64 Gcd(I64 a, I64 b){
return b ? Gcd(b, a % b) : a;
}
I64 Ext_Gcd(I64 a, I64 b, I64 &x, I64 &y){
}
I64 POWER(I64 a, I64 b, I64 c){
}
voidclear(){
}
I64 hash(I64 a){
}
voidINSERT_HASH(I64 i, I64 buf){
}
I64 bady_step_giant_step(I64 a, I64 b, I64 c){
}
int main(){
}