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, ...
随机推荐
- ***apache做301重定向的方法
将不带www的定向到带www去 方法一:加在httpd.conf 1.这里我使用mod_rewrite重写URL的方式来做,做之前朋友记得检查一下你的apache是否已经加载了rewrite模块.如图 ...
- 2887 Big String
splay瞎搞一下,正解是分块数组或分块链表,但是学不会啊! #include<cstdio> #include<cstdlib> #include<iostream&g ...
- activiti eclipse 插件不自动生成png
看下图,是不是很简单?
- django 简易博客开发 1 安装、创建、配置、admin使用
首先贴一下项目地址吧 https://github.com/goodspeedcheng/sblog 到现在位置项目实现的功能有: 1.后台管理使用Admin ,前端显示使用bootstrap 2. ...
- Guice 学习(八)AOP (面向切面的编程)
Guice的AOP还是非常弱的.眼下只支持方法级别上的,另外灵活性也不是非常高. 看例如以下演示样例: Guice支持AOP的条件是: 类必须是public或者package (default) 类不 ...
- mysql最新版中文参考手册在线浏览
MySQL是最流行的开放源码SQL数据库管理系统,具有快速.可靠和易于使用的特点.同时MySQL也是一种关联数据库管理系统,具有很高的响应速度和灵活性.又因为mysql拥有良好的连通性.速度和安全性, ...
- 基于FFMPEG SDK流媒体开发1---解码媒体文件流信息
近期项目涉及到流媒体等开发,因为有过开发经验深知其难度所在,没办法仅仅能又一次拾起,最新版的SDK被改的一塌糊涂,只是大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的 ...
- 磁盘扩容 磁盘阵列(Redundant Arrays of Independent Disks,RAID)
磁盘阵列(Redundant Arrays of Independent Disks,RAID) 云 500G 不够用 扩容 方案1 重建分区,由500G到1T,按历史增速,1年后再扩到1.5T, ...
- delphi的万能数据库操作
好多人都抱怨delphi没有提供一个可以把任意数据放入数据库的控件,虽然说用代码实现也不难,但是有控件会更方便,这次我终于还是抽出空来做了这么个控件,以后就可以直接拖放了.它支持把任意数据类型写入数据 ...
- GitHub Pages使用入门
1.什么是GitHub Pages GitHub Pages可以当做项目的Websites,GitHub Pages有两种最基本的用法: 作为你自己(或者组织)的网站(访问地址示例:http://us ...