poj 3243 Clever Y && 1467: Pku3243 clever Y【扩展BSGS】
扩展BSGS的板子
对于gcd(a,p)>1的情况
即扩展BSGS
把式子变成等式的形式: \( a^x+yp=b \)
设 \( g=gcd(a,p) \)
那么两边同时除以g就会变成: \( \frac{a}{g} a^{x-1}+y\frac{p}{g}=\frac{b}{g} \)
如此循环到ap互质,然后正常BSGS求即可
最后答案加上循环次数,即当前的x是经过几次减一得到的
注意有很多关于0和1的特判
以及这道题在bzoj上是可以用map的,但是poj上只能用hash
map版:
#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
using namespace std;
int a,b,p,ans;
map<int,int>mp;
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int ksm(int a,int b,int p)
{
int r=1;
while(b)
{
if(b&1)
r=(long long)r*a%p;
a=(long long)a*a%p;
b>>=1;
}
return r;
}
int BSGS(int a,int b,int p)
{
a%=p,b%=p;
if(b==1)
return 0;
int cnt=0,d=1;
for(int g=gcd(a,p);g!=1;g=gcd(a,p))
{
if(b%g)
return -1;
p/=g,b/=g;
d=(long long)d*a/g%p;
cnt++;
if(b==d)
return cnt;
}
mp.clear();
int m=ceil(sqrt(p)),t=b;
for(int i=0;i<m;i++)
{
mp[t]=i;
t=(long long)t*a%p;
}
int g=ksm(a,m,p);
t=(long long)d*g%p;
for(int i=1;i<=m+1;i++)
{
if(mp[t])
return cnt+i*m-mp[t];
t=(long long)t*g%p;
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&a,&p,&b)&&a+b+p)
{
if(p==1)
{
puts("0");
continue;
}
ans=BSGS(a,b,p);
if(ans==-1)
puts("No Solution");
else
printf("%d\n",ans);
}
return 0;
}
hash版,大概比map快三到四倍
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int mod=739391,N=2e6;
int a,b,p,ans,ti,v[N],con;
struct qwe
{
int b,v,ne;
}ha[N];
void ins(int w,int b,int va)
{//cout<<va<<endl;
if(v[w]!=ti)
{
v[w]=ti;
ha[w].v=va;
ha[w].b=b;
ha[w].ne=-1;
return;
}
for(;ha[w].ne!=-1;w=ha[w].ne)
if(ha[w].b==b)
return;
ha[w].ne=++con;
ha[con].ne=-1;
ha[con].v=va;
ha[con].b=b;
}
int find(int w,int b)
{
if(v[w]!=ti)
return 0;
for(;w!=-1;w=ha[w].ne)
if(ha[w].b==b)
return ha[w].v;
return 0;
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int ksm(int a,int b,int p)
{
int r=1;
while(b)
{
if(b&1)
r=(long long)r*a%p;
a=(long long)a*a%p;
b>>=1;
}
return r;
}
int BSGS(int a,int b,int p)
{
a%=p,b%=p;
if(b==1)
return 0;
int cnt=0,d=1;
for(int g=gcd(a,p);g!=1;g=gcd(a,p))
{
if(b%g)
return -1;
p/=g,b/=g;
d=(long long)d*a/g%p;
cnt++;
if(b==d)
return cnt;
}
con=mod,ti++;
int m=ceil(sqrt(p)),t=b;
for(int i=0;i<m;i++)
{
ins(t%mod,t,i);
t=(long long)t*a%p;
}
int g=ksm(a,m,p),now;
t=(long long)d*g%p;
for(int i=1;i<=m+1;i++)
{
if(now=find(t%mod,t))
return cnt+i*m-now;
t=(long long)t*g%p;
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&a,&p,&b)&&a+b+p)
{
if(p==1)
{
puts("0");
continue;
}
ans=BSGS(a,b,p);
if(ans==-1)
puts("No Solution");
else
printf("%d\n",ans);
}
return 0;
}
poj 3243 Clever Y && 1467: Pku3243 clever Y【扩展BSGS】的更多相关文章
- bzoj 1467: Pku3243 clever Y 扩展BSGS
1467: Pku3243 clever Y Time Limit: 4 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description 小 ...
- bzoj1467 Pku3243 clever Y
1467: Pku3243 clever Y Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 313 Solved: 181[Submit][Status ...
- 【EX_BSGS】BZOJ1467 Pku3243 clever Y
1467: Pku3243 clever Y Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 425 Solved: 238[Submit][Status ...
- 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 ...
- POJ 3243 Clever Y 扩展BSGS
http://poj.org/problem?id=3243 这道题的输入数据输入后需要将a和b都%p https://blog.csdn.net/zzkksunboy/article/details ...
- 【POJ 3243】Clever Y 拓展BSGS
调了一周,我真制杖,,, 各种初始化没有设为1,,,我当时到底在想什么??? 拓展BSGS,这是zky学长讲课的课件截屏: 是不是简单易懂.PS:聪哥说“拓展BSGS是偏题,省选不会考,信我没错”,那 ...
- POJ 3243 Clever Y(离散对数-拓展小步大步算法)
Description Little Y finds there is a very interesting formula in mathematics: XY mod Z = K Given X, ...
- poj 3243 Clever Y 高次方程
1 Accepted 8508K 579MS C++ 2237B/** hash的强大,,还是高次方程,不过要求n不一定是素数 **/ #include <iostream> #inclu ...
- [POJ 3243]Clever Y
Description Little Y finds there is a very interesting formula in mathematics: XY mod Z = K Given X, ...
随机推荐
- iOS 自动识别URL(链接)功能的实现
功能需求 在做“沃迪康”聊天功能时,甲方要求发送的网址要自动识别.并点击能自动跳转 功能难点 在实现过程中,所有的文字都是动态获取的,设置富文本属性时,不能按照常规的方法 解决方式 如果只是文字, ...
- HDU 2050 【dp】【简单数学】
题意: 中文. 思路: 不难发现数学规律是这样的,每次增加的划分区域的数量是每次增加的交点的数量再加一.然后就总结出了递推公式. #include<stdio.h> ]; int main ...
- ORACLE DTRACE DOC
http://docs.oracle.com/cd/E19253-01/817-6223/
- js的基础(平民理解的执行上下文/调用堆栈/内存栈/值类型/引用类型)
与以前的切图比较,现在的前端开发对js的要求似乎越来越高,在开发中,我们不仅仅是要知道如何运用现有的框架(react/vue/ng), 而且我们对一些基础的知识的依赖越来越大. 现在我们就用平民的方法 ...
- windows下开发PHP扩展dll(无需Cygwin)
windows下开发php扩展网上很多资料都说需要Cygwin,其实完全可以不必安装该东东.没错,是可以在linux下生成骨架后拷到windos下来用,但是,如果没有linux环境呢?什么,装虚拟机? ...
- SQL 主机
SQL 主机 SQL 主机 如果您想要您的网站存储数据在数据库并从数据库显示数据,您的 Web 服务器必须能使用 SQL 语言访问数据库系统. 如果您的 Web 服务器托管在互联网服务提供商(ISP, ...
- Android 项目导入常见错误
1.SDK版本号不正确应,你能够打开你项目中的project.properties文件,改动target=android-18(我这是18) ,将18改 为14(其它都能够),再改回18会又一次载入. ...
- 【Sublime】Sublime Text 2集成TortoiseSVN插件
作者:zhanhailiang 日期:2014-09-30 1. 下载TortoiseSVN.将其安装在默认位置: 2. 使用Sublime包管理器下载安装TortoiseSVN Plugin,安装后 ...
- cmd下复制粘贴
cmd下复制粘贴的快捷操作方式 工具/原料 系统cmd 步骤/方法 1 如右图,右键命令提示符窗口的标题栏,选择属性. 2 选择“编辑选项”里的“快速编辑模式”,并确定之: 3 在弹出的应用选择提示框 ...
- Android数据与服务器交互的GET,POST,HTTPGET,HTTPPOST的使用
Android有这几种方式,可以提交数据到服务器,他们是怎么使用的呢,这里我们来探讨一下. 这里的例子用的都是提交客户端的用户名及密码,同时本节用到的StreamTools.readInputStre ...