题目大意就是求 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. Android 线程池系列教程(3) 创建线程池

    Creating a Manager for Multiple Threads 上一课  下一课 1.This lesson teaches you to Define the Thread Pool ...

  2. SP CAML工具

    直接一直使用CAML做一些简单的SP列表查询,突然想对CAML进一步了解,于是找到两个常用工具,做以记录: 1 Caml Query Builder : 用于编写CAML查询,对初学者可以了解查询语句 ...

  3. 单例模式及php实现

    单例模式: 单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法. 单例模式的要点有三个:一 ...

  4. 使用Jquery1.9 版本 来实现全选

    在使用Jquery实现全选以及反选的时候, 使用attr()实现的时候,在浏览器第一次运行可以全选,但是第二次再全选,不管用.  通过查找资料,用 prop()方法代替attr()方法就行了. 注意: ...

  5. VS项目属性配置总结

    以下是针对VS2013下的VC++项目: Debug和Release说明: Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进 ...

  6. 关于Qt模态框总汇

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7285710.html 父窗体为QMainWindow: 当子窗体为: 1.QWidget,需要设置 this- ...

  7. 临时笔记 Protection

    如果操作系统不使用处理器的多任务机制,它仍然需要为栈创建至少一个TSS 当程序通过调用门改变特权级的时候,处理器执行下面的步骤切换栈,并且执行被调用的程序在新的特权级 1. 使用目标代码段的DPL从T ...

  8. CentOS 6.4 linux下编译安装 LNMP环境

    1.nginx编译安装 2.PHP编译安装 3.mysql编译安装 4.NGINX配置模板 5.CentOS 6.4 php-fpm 添加service 添加平滑启动/重启

  9. ArrayList源码分析(基于JDK1.8)

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...

  10. (转)淘淘商城系列——使用maven构建工程时出现的错误

    http://blog.csdn.net/yerenyuan_pku/article/details/72690846 我觉得maven就他妈是一个傻逼,反正我是对它无语了.昨天刚刚使用maven构建 ...