【poj3243-Clever Y】高次同余方程-拓展BabyStepGiantStep
http://poj.org/problem?id=3243
题意:给定X,Z,K,求一个最小的Y满足XY mod Z = K。
关于拓展BSGS的详细解释我写了一篇博文:http://www.cnblogs.com/KonjakJuruo/p/5178600.html
题解:BSGS的拓展版本(因为X和Z不一定互质)。这道题挺坑的,如果K>=Z不是输出无解而是让K%=Z。
算是BSGS的模板题,我打了两种版本,就是二分查找和hash。对比两次提交来看,二分省空间,耗时间;Hash省时间,耗空间。
另外,find部分可以不用二分,而用hash解决。感觉大部分情况下还是hash比较快,但是比较耗空间。
把你需要存的数,即x的0~m次方算出来,假设是t,我们设m=1<<16-1,然后用t异或^m得nt(就是取t二进制后的15位进行hash),然后存到hash表里面去。如果t的位置目前没有存数,那么我们就直接存到hash[t]上去,如果t位置已经存了数(因为后15位为t的可能有多种情况),我们就在len除增加一个位置,把nt存到那里面去,然后hash[t].next=len,把位置记录下来,这应该就相当于一条链了。查找的时候循着这条链找下去即可,链的尽头的next用-1标记。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std; typedef long long LL;
const int N=;
bool bk;
LL X,Z,K,a,b,c,m,k,sum,am,bl;
struct node{
LL d,id;
}bit[N],p[N]; bool cmp(node x,node y){
if(x.d!=y.d) return x.d<y.d;
return x.id<y.id;
} LL gcd(LL u,LL v)
{
if(v==) return u;
return gcd(v,u%v);
} LL find(LL x)
{
int l=,r=bl;
while(l<=r)
{
int mid=(l+r)>>;
if(bit[mid].d==x) return bit[mid].id;
if(bit[mid].d>x) r=mid-;
if(bit[mid].d<x) l=mid+;
}
return -;
} void exgcd(LL u,LL v,LL &x,LL &y)
{
if(v==) {x=,y=;return ;}
LL tx,ty;
exgcd(v,u%v,tx,ty);
x=ty;y=tx-(u/v)*ty;
return;
} LL BSGS()
{
LL t,g,x,y,pm;
a=X;b=K;c=Z;k=;sum=;bk=;bl=;t=%c;
for(int i=;i<=;i++){//避免a的负数次方
if(t==b) return i;
t=t*a%c;
}
while((g=gcd(X,c))!=)
{
k=(k*X/g)%c;//k记得要mod,否则溢出
c/=g;
if(b%g) return -;
b/=g;
sum++;
}
m=(LL)(ceil((double)sqrt((double)c)));//要约分之后再求m
p[].d=k%c;
p[].id=;
pm=;//pm是不用*k的
for(int i=;i<=m;i++)
p[i].d=p[i-].d*a%c,pm=pm*a%c,p[i].id=i;
sort(p,p++m,cmp);
bit[]=p[];bl=;
for(int i=;i<=m;i++)
{
if(p[i].d!=p[i-].d) bit[++bl]=p[i];
}
exgcd(pm,c,x,y);
am=(x%c+c);//避免am=0 t=b;
x=find(b);
if(x!=-) return x;
for(int i=;i<=bl;i++)
{
t*=am;t%=c;
x=find(t);
if(x!=-)
return i*m+x;
}
return -;
} int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
while()
{
scanf("%I64d%I64d%I64d",&X,&Z,&K);
if(!X && !Z && !K) return ;
K%=Z;
LL ans=BSGS();
if(ans!=-) printf("%I64d\n",ans+sum);
else printf("No Solution\n");
}
return ;
}
BSGS-二分
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std; typedef long long LL;
const LL N=,Max=(<<)-;
bool bk;
LL X,Z,K,len;
bool vis[];
struct node{
LL d,id,next;
}hash[*Max]; int exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==) {x=,y=;return a;}
LL tx,ty;
LL d=exgcd(b,a%b,tx,ty);
x=ty;y=tx-(a/b)*ty;
return d;
} void ins(LL d,LL id)
{
LL t=d&Max;
if(!vis[t]) {
vis[t]=;
hash[t].d=d,hash[t].id=id,hash[t].next=-;
return ;
}
for(;hash[t].next!=-;t=hash[t].next))//注意是hash[t].next!=-1
{
if(hash[t].d==d) return;
}
hash[t].next=++len;
hash[len].d=d;hash[len].id=id;hash[len].next=-;
} LL find(LL d)
{
LL t=d&Max;
if(!vis[t]) return -;
for(;t!=-;t=hash[t].next)
{
if(hash[t].d==d) return hash[t].id;
}
return -;
} LL BSGS()
{
LL t,g,x,y,pm,a,b,c,m,k,sum,am;
a=X;b=K;c=Z;k=;sum=;t=%c;
for(int i=;i<=;i++){
if(t==b) return i;
t=t*a%c;
}
while((g=exgcd(X,c,x,y))!=)
{
k=(k*X/g)%c;
c/=g;
if(b%g) return -;
b/=g;
sum++;
}
m=(LL)(ceil((double)sqrt((double)c)));
ins(k,);
t=k;pm=;
for(int i=;i<=m;i++)
{
t=t*a%c,pm=pm*a%c;
ins(t,i);
}
exgcd(pm,c,x,y);
am=x%c+c;
t=b;
for(int i=;i<=m;i++)
{
x=find(t);
if(x!=-) return i*m+x+sum;
t=t*am%c;
}
return -;
} int main()
{
// freopen("a.in","r",stdin);
// freopen("b.out","w",stdout);
while()
{
scanf("%I64d%I64d%I64d",&X,&Z,&K);
if(!X && !Z && !K) return ;
K%=Z;len=Max;
memset(vis,,sizeof(vis));
LL ans=BSGS();
if(ans!=-) printf("%I64d\n",ans);
else printf("No Solution\n");
}
return ;
}
BSGS-Hash
【poj3243-Clever Y】高次同余方程-拓展BabyStepGiantStep的更多相关文章
- 【数论】【ex-BSGS】poj3243 Clever Y
用于求解高次同余方程A^x≡B(mod C),其中C不一定是素数. http://blog.csdn.net/tsaid/article/details/7354716 这篇题解写得最好. 那啥,这题 ...
- 高次同余方程模板BabyStep-GiantStep
/************************************* ---高次同余方程模板BabyStep-GiantStep--- 输入:对于方程A^x=B(mod C),调用BabySt ...
- poj3243 Clever Y[扩展BSGS]
Clever Y Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 8666 Accepted: 2155 Descript ...
- luogu2485 [SDOI2011]计算器 poj3243 Clever Y BSGS算法
BSGS 算法,即 Baby Step,Giant Step 算法.拔山盖世算法. 计算 \(a^x \equiv b \pmod p\). \(p\)为质数时 特判掉 \(a,p\) 不互质的情况. ...
- 【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep
http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意:裸题... 关于拓展BSGS的详细解释我写了一篇博文:http://www.cnblogs.com/ ...
- POJ 3243 Clever Y(离散对数-拓展小步大步算法)
Description Little Y finds there is a very interesting formula in mathematics: XY mod Z = K Given X, ...
- 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)
什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...
- [拓展Bsgs] Clever - Y
题目链接 Clever - Y 题意 有同余方程 \(X^Y \equiv K\ (mod\ Z)\),给定\(X\),\(Z\),\(K\),求\(Y\). 解法 如题,是拓展 \(Bsgs\) 板 ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
随机推荐
- [CentOS 6.5 X64]讓firefox java plugin 啟動
到ORACLE下載JRE http://www.oracle.com/technetwork/java/javase/downloads/index.html 我是X64所以下載 jre-7-linu ...
- 通过firefox+ProxySelector+dtunnel_lite实现代理上网
通过firefox+ProxySelector+dtunnel_lite实现代理上网 dtunnel_lite:http://dog-tunnel.tk/下载lite版本就可以 远端:./dtunne ...
- python实现树莓派生成并识别二维码
python实现树莓派生成并识别二维码 参考来源:http://blog.csdn.net/Burgess_Liu/article/details/40397803 设备及环境 树莓派2代 官方系统R ...
- linux 编译C应用程序的Makefile
CC=arm-linux-gcctarget=testsource=test.call: $(target)$(target): $(source) $(CC) -o $@ $<.PHONY: ...
- Linux下强制修改root密码方法(图)
如果Linux操作系统的root密码,那怎么办呢?方法很多,下面再给大家介绍一种. [1] 进入以下画面后,按下e按钮,进入编辑模式: [2]进入以下的画面后,选择如下所示的选项,再次按下e按钮: 然 ...
- android讯飞语音开发常遇到的问题
场景:android项目中共使用了3个语音组件:在线语音听写.离线语音合成.离线语音识别 11208:遇到这个错误,授权应用失败,先检查装机量(3台测试权限),以及appid的申请时间(35天期限), ...
- union与union all的区别
首先说下union与join的区别 1.union是以行增加的方式,进行连接:join是以列增加的方式进行连接: 2.union连接查询的两个表的字段必须要一一对应,数目相等:join则没有要求,但是 ...
- 我是IT小小鸟
我是IT小小鸟读后感 世界上没有一蹴而就的成功者,只有头悬梁锥刺股的奋斗者.蜉蝣向往大鹏的辉煌,却不曾知大鹏以往的汗水.蜉蝣之所以为蜉蝣,是因为它犹如井底之蛙,目光短浅,之盲目地羡慕成功者,而大鹏之所 ...
- TEST ON 平安夜
1.前言 = = 感觉自己其实没发过关于考试的博客过... 今天是一个平安的夜晚,漆黑的夜被霓虹划分成网络,很适合发题. 2.num9九数码问题 传统8数码改一下...只询问一个状态,所以很容易搞,正 ...
- Mrt render
mutil render target Pixel shder输出一个结构体 Out.f4Color Out.f4Normal 这步在渲染物体的shader里 在application setcolo ...