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标记。

——引用自http://www.cnblogs.com/Konjakmoyu/p/5180458.html

 #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的更多相关文章

  1. 【数论】【ex-BSGS】poj3243 Clever Y

    用于求解高次同余方程A^x≡B(mod C),其中C不一定是素数. http://blog.csdn.net/tsaid/article/details/7354716 这篇题解写得最好. 那啥,这题 ...

  2. 高次同余方程模板BabyStep-GiantStep

    /************************************* ---高次同余方程模板BabyStep-GiantStep--- 输入:对于方程A^x=B(mod C),调用BabySt ...

  3. poj3243 Clever Y[扩展BSGS]

    Clever Y Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8666   Accepted: 2155 Descript ...

  4. luogu2485 [SDOI2011]计算器 poj3243 Clever Y BSGS算法

    BSGS 算法,即 Baby Step,Giant Step 算法.拔山盖世算法. 计算 \(a^x \equiv b \pmod p\). \(p\)为质数时 特判掉 \(a,p\) 不互质的情况. ...

  5. 【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep

    http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意:裸题... 关于拓展BSGS的详细解释我写了一篇博文:http://www.cnblogs.com/ ...

  6. POJ 3243 Clever Y(离散对数-拓展小步大步算法)

    Description Little Y finds there is a very interesting formula in mathematics: XY mod Z = K Given X, ...

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

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

  8. [拓展Bsgs] Clever - Y

    题目链接 Clever - Y 题意 有同余方程 \(X^Y \equiv K\ (mod\ Z)\),给定\(X\),\(Z\),\(K\),求\(Y\). 解法 如题,是拓展 \(Bsgs\) 板 ...

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

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

随机推荐

  1. 找到一个学习bootstrap的好网站

    http://www.w3cschool.cc/bootstrap/bootstrap-css-overview.html

  2. Xcode全局断点

    1.将导航器视图切换到断点导航器视图下,也可以用快捷键Command+7一步搞定,键盘是window风格的用户Command键是win键(有微软logo),然后点击左下角的+号,选择Add Symbo ...

  3. django概述

    一.django的特点 1.提供一体化的web解决方案,什么叫一体化:mvc 2.等你玩儿牛逼了可以拔插组件,换成自己顺手或者更牛逼的组件

  4. 5.防止FPGA设计中综合后的信号被优化

    随着FPGA设计复杂程度越来越高,芯片内部逻辑分析功能显得越来越重要.硬件层次上的逻辑分析仪价格十分昂贵,而且操作比较复杂.目前,FPGA芯片的两大供应商都为自己的FPGA芯片提供了软件层面上的逻辑分 ...

  5. UIDatePicker倒计时 swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  6. 老周的ABP框架系列教程 -》 一、框架理论初步学习

    老周的ABP框架系列教程 -- 一.框架理论初步学习   1. ABP框架的来源与作用简介 1.1  简介 1.1.1       ABP框架全称为"ASP.NET Boilerplate ...

  7. 【转】eclipse下使用hibernate tools实现hibernate逆向工程

    一.基本环境 Eclipse 3.6 AppFuse Struts2 2.1.0 JBoss Hibernate Tools 3.4.0 二.JBoss Hibernate Tools 3.4.0安装 ...

  8. sql数据库的表连接方式图文详解

    sql数据库表连接,主要分为:内连接.外连接(左连接.右连接 .全连接).交叉连接,今天统一整合一下,看看他们的区别.   首先建表填充值. 学生表:student(id,姓名,年龄,性别 ) 成绩表 ...

  9. web开发--文档下载

    GOOGLE在线文档下载地址分享(GOOGLE的文档地址暂不能用了,会放在其它位置..) GOOGLE的在线文档功能好象挂掉了...等找个其它存放的位置把这些文档再上传上去... 存在GOOGLE里面 ...

  10. 线段树--Color the ball(多次染色问题)

    K - Color the ball Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...