【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)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
随机推荐
- NE、EQ等比较操作符的意义
比较所有的 字段类型 要比较所有 的字段类型 ,可以在逻 辑表达式中 使用下列运 算符: <运算符>含 义 EQ 等于 = 等于 NE 不 等于 <> 不 等于 >< ...
- 通过Roslyn构建自己的C#脚本
通过Roslyn构建自己的C#脚本 在下一代的C#中,一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为一种可在代码中调用的服务.最 ...
- Window7上搭建symfony开发环境(PEAR)
http://blog.csdn.net/kunshan_shenbin/article/details/7162243 1. 更新PEAR 进入PHP所在目录,找到go-pear.bat并双击. 一 ...
- 007--VS2013 C++ 显示位图半透明化
以后所有图片都放在根目录下: 如有另放,会特别注明 //全局变量HBITMAP bg,girl;HDC mdc; //起始坐标const int xstart = 50;const int ystar ...
- My First Django Project (2)
1. 接下来是比较重要的VIEWS.py,您将会比较多的时间在这.有点想.net里面的aspx的cs概念,而aspx就是和接下来要创建的template html相似! 下面是我创建的一个view d ...
- 设置xx-net,访问youtube等国外网站
配合使用chrome+xx-net,就可以免费访问youtube等外网了.步骤如下: 1. 按照https://github.com/XX-net/XX-Net/wiki/%E4%BD%BF%E7%9 ...
- 20145129 《Java程序设计》第8周学习总结
20145129 <Java程序设计>第8周学习总结 教材学习内容总结 NIO NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),rewind(),fli ...
- C#新语法特性前瞻
今天逛微软的UserVoice site发现了几个有很有用,也很可能被添加到新版C#中的语法,当然也可能被推迟到下一版,拿出来给大家分享一下. 另外还没投票的可以去为自己最想要的新特性投票,有兴趣的可 ...
- Careercup - Microsoft面试题 - 5428361417457664
2014-05-11 03:37 题目链接 原题: You have three jars filled with candies. One jar is filled with banana can ...
- Extjs 选择元素涉及方法总结
本文主要是解释Extjs在使用过程中使用的相关选择方法: 1.首先解释第一组概念: Ext.get(String/HTMLElement/Ext.Element el) Ext.getCmp(Stri ...