题目大意就是求 a^x = b(mod c) 中的x

用一般的baby step giant step 算法会超时

这里参考的是http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4

map平衡树查找值

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
#define ll long long int q_pow(int a , int b , int mod)
{
ll ans = ;
while(b)
{
if(b&) ans =((ll)ans*a)%mod;
a = ((ll)a*a)%mod;
b>>=;
}
return ans;
} int gcd(int a , int b)
{
if(b == )return a;
else return gcd(b,a%b);
} int ex_gcd(int a , int &x , int b , int &y)
{
if(b == ){
x= , y=;
return a;
}
int ans = ex_gcd(b , x , a%b , y);
int t = x;
x=y , y = t-a/b*y;
return ans;
} int inv(int a , int b , int mod)
{
int x , y , d;
d = ex_gcd(a , x , mod , y);
int e = (ll)x*b%mod;
return e<?e+mod:e;
} int BabyStep(int A,int B,int C){
map<int,int> Hash;
ll buf=%C,D=buf,K;
int i,d=,tmp;
for(i=;i<=;buf=buf*A%C,++i)
if(buf==B) return i;
while((tmp=gcd(A,C))!=)
{
if(B%tmp)return -;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
Hash.clear();
int M=(int)ceil(sqrt((double)C));
for(buf=%C,i=;i<=M;buf=buf*A%C,++i)
if(!Hash.count((int)buf))Hash[(int)buf]=i;
for(i=,K=q_pow((ll)A,M,C);i<=M;D=D*K%C,++i)
{
tmp=inv(D,B,C);
if(tmp>=&&Hash.count(tmp))return i*M+Hash[tmp]+d;
}
return -;
}
int main()
{
// freopen("a.in" ,"r" , stdin);
int k , p , n;
while(scanf("%d%d%d" , &k , &p , &n) == )
{
if(n>=p){
puts("Orz,I can’t find D!");
continue;
}
int ans = BabyStep(k , n , p);
if(ans == -) puts("Orz,I can’t find D!");
else printf("%d\n" , ans);
}
return ;
}

hash表查找值(效率高很多)hash是线性查找:

 #include<iostream>
#include<map>
#include<cmath>
#include <cstdio>
using namespace std;
typedef long long LL;
const int maxn = ;
struct hash{
int a,b,next;
}Hash[maxn << ];
int flg[maxn + ];
int top,idx;
//hash值插入
void ins(int a,int b){
int k = b & maxn;
if(flg[k] != idx){
flg[k] = idx;
Hash[k].next = -;
Hash[k].a = a;
Hash[k].b = b;
return ;
}
while(Hash[k].next != -){
if(Hash[k].b == b) return ;
k = Hash[k].next;
}
Hash[k].next = ++ top;
Hash[top].next = -;
Hash[top].a = a;
Hash[top].b = b;
}
//hash值查找
int find(int b){
int k = b & maxn;
if(flg[k] != idx) return -;
while(k != -){
if(Hash[k].b == b) return Hash[k].a;
k = Hash[k].next;
}
return -;
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int ext_gcd(int a,int b,int& x,int& y)
{
int t,ret;
if (!b){x=,y=;return a;}
ret=ext_gcd(b,a%b,x,y);
t=x,x=y,y=t-a/b*y;
return ret;
}
int Inval(int a,int b,int n){
int x,y,e;
ext_gcd(a,n,x,y);
e=(LL)x*b%n;
return e<?e+n:e;
}
int pow_mod(LL a,int b,int c)
{
LL ret=%c;
a%=c;
while(b){
if(b&)ret=ret*a%c;
a=a*a%c;
b>>=;
}
return ret;
}
int BabyStep(int A,int B,int C){
top = maxn; ++ idx;
LL buf=%C,D=buf,K;
int i,d=,tmp;
for(i=;i<=;buf=buf*A%C,++i)
if(buf==B)return i;
while((tmp=gcd(A,C))!=){
if(B%tmp)return -;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
int M=(int)ceil(sqrt(C+0.5));
for(buf=%C,i=;i<=M;buf=buf*A%C,++i)
ins(i,buf);
for(i=,K=pow_mod((LL)A,M,C);i<=M;D=D*K%C,++i){
tmp=Inval((int)D,B,C);
int w ;
if(tmp>=&&(w = find(tmp)) != -) return i*M+w+d;
}
return -;
}
int main(){
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF){
if(B>C){
puts("Orz,I can’t find D!");
continue;
}
int tmp=BabyStep(A,B,C);
if(tmp<)
puts("Orz,I can’t find D!");
else printf("%d\n",tmp);
}
return ;
}

HDU 2815 扩展baby step giant step 算法的更多相关文章

  1. HDU 2815 Mod Tree 离散对数 扩张Baby Step Giant Step算法

    联系:http://acm.hdu.edu.cn/showproblem.php?pid=2815 意甲冠军: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...

  2. 【学习笔记】Baby Step Giant Step算法及其扩展

    1. 引入 Baby Step Giant Step算法(简称BSGS),用于求解形如\(a^x\equiv b\pmod p\)(\(a,b,p\in \mathbb{N}\))的同余方程,即著名的 ...

  3. 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法

    先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝  扩展Baby Step Gian ...

  4. 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 ...

  5. 『高次同余方程 Baby Step Giant Step算法』

    高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...

  6. [置顶] hdu2815 扩展Baby step,Giant step入门

    题意:求满足a^x=b(mod n)的最小的整数x. 分析:很多地方写到n是素数的时候可以用Baby step,Giant step, 其实研究过Baby step,Giant step算法以后,你会 ...

  7. 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

    什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...

  8. POJ 2417 Discrete Logging ( Baby step giant step )

    Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3696   Accepted: 1727 ...

  9. 【POJ2417】baby step giant step

    最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step ...

随机推荐

  1. Oracle报错:"ORA-18008: 无法找到 OUTLN 方案 "的解决方案

    Oracle报错:"ORA-18008: 无法找到 OUTLN 方案 "的解决方案     今天连接到Oracle报错:ORA-18008: 无法找到 OUTLN 方案,前天还用得 ...

  2. JAVA面试题最全集

      JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基 ...

  3. iOS9导入高德地图报错App Transport Security has blocked...

    App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Te ...

  4. 221 Maximal Square 最大正方形

    在一个由0和1组成的二维矩阵内,寻找只包含1的最大正方形,并返回其面积.例如,给出如下矩阵:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0返回 4. 详见:https://l ...

  5. 206 Reverse Linked List 反转链表

    反转一个单链表.进阶:链表可以迭代或递归地反转.你能否两个都实现一遍?详见:https://leetcode.com/problems/reverse-linked-list/description/ ...

  6. [转]C#委托Action、Action<T>、Func<T>、Predicate<T>

    CLR环境中给我们内置了几个常用委托Action. Action<T>.Func<T>.Predicate<T>,一般我们要用到委托的时候,尽量不要自己再定义一 个 ...

  7. android开发学习--网络请求框架RxJava+Retrofit

    看了好多的博客,终于弄清楚了Rxjava和Retrofit,给大家推荐几个不错的文章: https://gank.io/post/56e80c2c677659311bed9841 这个文章是只用Ret ...

  8. php(一)

    PHP (Hypertext preprocessor 超文本预处理器) 1.环境工具 Xampp等工具 2.apache配置 默认的Apache路径是  c:/xampp/apache 文件夹 可以 ...

  9. jquery 序列化form表单

    1.为什么要将form表单序列化? ajax上传form表单的原始方式,是将form表单中所需要的键值对先获取,然后再组装成数据(两种方式:http:localhost:8080/test.do?pe ...

  10. 解决jquery与其他库的冲突

    1.jquery在其他库之后导入 第一种: jQuery.noConflict();//将变量$的控制权限交给其他类库,即将$的控制权让渡给其他类库 jQuery(function(){ jQuery ...