HDU 2815 扩展baby step giant step 算法
题目大意就是求 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 算法的更多相关文章
- HDU 2815 Mod Tree 离散对数 扩张Baby Step Giant Step算法
联系:http://acm.hdu.edu.cn/showproblem.php?pid=2815 意甲冠军: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...
- 【学习笔记】Baby Step Giant Step算法及其扩展
1. 引入 Baby Step Giant Step算法(简称BSGS),用于求解形如\(a^x\equiv b\pmod p\)(\(a,b,p\in \mathbb{N}\))的同余方程,即著名的 ...
- 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法
先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝 扩展Baby Step Gian ...
- 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 ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
- [置顶] hdu2815 扩展Baby step,Giant step入门
题意:求满足a^x=b(mod n)的最小的整数x. 分析:很多地方写到n是素数的时候可以用Baby step,Giant step, 其实研究过Baby step,Giant step算法以后,你会 ...
- 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)
什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...
- POJ 2417 Discrete Logging ( Baby step giant step )
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3696 Accepted: 1727 ...
- 【POJ2417】baby step giant step
最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step ...
随机推荐
- 转 mysql oracle 指定rand随机数范围
若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...
- 自己制作ssl证书
首先执行如下命令生成一个key openssl genrsa -des3 -out ssl.key 1024 然后他会要求你输入这个key文件的密码.不推荐输入.因为以后要给nginx使用.每次r ...
- 转】用Mahout构建职位推荐引擎
原博文出自于: http://blog.fens.me/hadoop-mahout-recommend-job/ 感谢! 用Mahout构建职位推荐引擎 Hadoop家族系列文章,主要介绍Hadoop ...
- poj3050 Hopscotch
思路: 水题. 实现: #include <iostream> #include <cstdio> #include <set> using namespace s ...
- 一起来学SpringBoot(十七)优雅的参数校验
参数校验在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动方法内代码显得冗长每次要看哪些参数 ...
- col - 过滤掉输入中的反向换行符
SYNOPSIS(总览) col [-bfx ] [ Fl l Ar num ] DESCRIPTION(描述) Col 过滤掉反向(以及半反向)换行符(LF: line feed or NL: ne ...
- 導出Excel方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- JAVA编程不得不看的几本经典书籍
为了帮助对java编程感兴趣的同学更好.更快的提高编程技术,武汉北大青鸟光谷校区专业老师在此推荐几本学习编程非常有用的书籍,以供大家参考. 入门类 1.<java从入门到精通>(第3版) ...
- 常用的HTTP方法有哪些?
GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器POST:用于传输数据给服务器,主要功能与GET方法类似,但一般推荐使用POST方式.PUT: 传输数据,报文 ...
- 四种方案解决ScrollView嵌套ListView问题 [复制链接]
以下文章转自@安卓泡面 在工作中,曾多次碰到ScrollView嵌套ListView的问题,网上的解决方法有很多种,但是杂而不全.我试过很多种方法,它们各有利弊. 在这里我将会从使用ScrollVie ...