BSGS+exBSGS POJ2417+POJ3243
a^x=b(mod p)求x,利用分块的思想根号p的复杂度求答案,枚举同余式两端的变量,用hash的方法去找最小的答案(PS:hash看上去很像链式前向星就很有好感)。然后如果p不是质数时,就利用同余式的性质,把(a,p)的最大公约数除掉,然后把残缺的部分用一个d存一下,就可以转化为普通的BSGS了。这里那个在while中的特判b==d要不要我也不确定,加了肯定对。当然一个明确的特判是b==1时这时直接返回答案为0就OK。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<cstring>
#include<string>
#define ll long long
#define pb push_back
#define _mp make_pair
#define db double
using namespace std;
const int maxn=100007;
const int maxm=100005;
ll has[maxn];
ll fir[maxn],nxt[maxn],ans[maxn];
int tot;
ll a,b,p;
void add(ll x,ll k)
{
ll p=x%maxn;
ans[++tot]=k;nxt[tot]=fir[p];fir[p]=tot;
has[tot]=x;
}
ll query(ll x)
{
ll p=x%maxn;
for(int i=fir[p];i!=-1;i=nxt[i])
{
if(has[i]==x)return ans[i];
}
return -1;
}
ll bsgs(ll a,ll b,ll p)
{
if(b==1)return 0ll;
ll tmp=1,d=1,cnt=0;
while((tmp=__gcd(a,p))!=1)
{
if(b%tmp)return -1;
b/=tmp;p/=tmp;d=d*(a/tmp)%p;cnt++;
if(b==d)return cnt;//???
}
ll m=ceil(sqrt((double)p));
ll q=1;
for(ll i=0;i<m;i++)
{
add((q*b)%p,i);q=(q*a)%p;
}
for(ll i=m;i<=p+m;i+=m)
{
d=(d*q)%p;
ll tt=query(d);
if(tt!=-1)return i-tt+cnt;
}
return -1;
}
int main()
{
while(scanf("%lld%lld%lld",&a,&p,&b))
{
if(!p&&!a&&!b)return 0;
memset(fir,-1,sizeof(fir));
tot=0;
ll tt=bsgs(a,b,p);
if(tt==-1)printf("No Solution\n");
else printf("%lld\n",tt);
} }
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<cstring>
#include<string>
#define ll long long
#define pb push_back
#define _mp make_pair
#define db double
using namespace std;
const int maxn=1000007;
const int maxm=100005;
ll has[maxn];
int fir[maxn],nxt[maxn],ans[maxn];
int tot;
ll a,b,p;
void add(ll x,int k)
{
int p=x%maxn;
ans[++tot]=k;nxt[tot]=fir[p];fir[p]=tot;
has[tot]=x;
}
int query(ll x)
{
int p=x%maxn;
for(int i=fir[p];i!=-1;i=nxt[i])
{
if(has[i]==x)return ans[i];
}
return -1;
}
ll bsgs(ll a,ll b,ll p)
{
if(b==1)return 0ll;
ll m=ceil(sqrt((double)p));
ll q=1,x=1;
for(ll i=0;i<m;i++)
{
add((q*b)%p,i);q=(q*a)%p;
}
x=(x*q)%p;
for(ll i=m;i<=p;i+=m)
{
ll tt=query(x);
if(tt!=-1)return i-tt;
x=(x*q)%p;
}
return -1;
}
int main()
{
while(~scanf("%lld%lld%lld",&p,&a,&b))
{
memset(fir,-1,sizeof(fir));
tot=-1;
ll tt=bsgs(a,b,p);
if(tt==-1)printf("no solution\n");
else printf("%lld\n",tt);
} }
BSGS+exBSGS POJ2417+POJ3243的更多相关文章
- BSGS&EXBSGS 大手拉小手,大步小步走
大步小步走算法处理这样的问题: A^x = B (mod C) 求满足条件的最小的x(可能无解) 其中,A/B/C都可以是很大的数(long long以内) 先分类考虑一下: 当(A,C)==1 即A ...
- BSGS&ExBSGS
BSGS&ExBSGS 求解形如 \[a^x\equiv b\pmod p\] 的高次同余方程 BSGS 假装\(gcd(a,p)=1\). 设\(m=\lceil\sqrt p \rceil ...
- [note]BSGS & exBSGS
BSGS (感觉这东西还是要写一下) BSGS主要用于求解形如\(x^k=y\pmod p\)(注意这里p与x互质)这样的方程的最小正整数解的问题 设\(m=\lceil\sqrt p\rceil,k ...
- 算法笔记--BSGS && exBSGS 模板
https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...
- BSGS && EXBSGS
基础BSGS 用处是什么呢w 大步小步发(Baby-Step-Giant-Step,简称BSGS),可以用来高效求解形如\(A^x≡B(mod C)\)(C为素数)的同余方程. 常用于求解离散对数问题 ...
- 【数论】【ex-BSGS】poj3243 Clever Y
用于求解高次同余方程A^x≡B(mod C),其中C不一定是素数. http://blog.csdn.net/tsaid/article/details/7354716 这篇题解写得最好. 那啥,这题 ...
- Noip前的大抱佛脚----数论
目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...
- 各种友(e)善(xin)数论总集(未完待续),从入门到绝望
目录 快速幂 扩展欧几里得 GCD 扩展欧几里得 同余系列 同余方程 同余方程组 一点想法 高次同余方程 BSGS exBSGS 线性筛素数 埃式筛 欧拉筛 欧拉函数 讲解 两道水题 法雷级数 可见点 ...
- REHの收藏列表
搬运自本人的AcWing,所以那里的文章会挺多. 友链(同类文章) :bztMinamoto 世外明月 mlystdcall 新人手册:AcWing入门使用指南 前言 有看到好文欢迎推荐(毛遂自荐也可 ...
随机推荐
- 动态更新Icon
动态更改图标主要用到activity-alias和PackageManager的setComponentEnabledSetting方法.具体步骤如下: 1.在AndroidManifest.xml中 ...
- 算法:数组中和为s的两个数字
@问题 :题目描述输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述:对应每个测试案例,输出两个数,小的先输出.@思路: 两个 ...
- webpack安装、基本配置
文章结构: 什么是webpack? 安装webpack webpack基本配置 一.什么是webpack? 在学习react时发现大部分文章都是react和webpack结合使用的,所以在学react ...
- JVM远程调试功能
有时候想调试线上的程序 可以启用远程调试功能 在本地调试远程代码. 远程JVM启用调试模式 /usr/local/jdk/bin/java -server -Xms256m -Xmx256m -XX: ...
- LeetCode算法题-Design HashSet(Java实现)
这是悦乐书的第298次更新,第317篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第166题(顺位题号是705).不使用任何内建的hash表库设计一个hash集合,应包含 ...
- oc中的委托模式
通过一个例子来理解委托模式 首先定义个协议 协议(protocol) :它可以声明一些必须实现的方法和选择实现的方法 (在java中称为接口) // // StudentDelegate.h // ...
- 【Linux基础】mount报错:mount.nfs: Remote I/O error
问题描述:mount 报错:mount.nfs: Remote I/O error 挂载时需要指明版本,由于NFS服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号. 由 ...
- Cloudera Manager(CDH5)内部结构、功能包括配置文件、目录位置等
1. 相关目录 /var/log/cloudera-scm-installer : 安装日志目录./var/log/* : 相关日志文件(相关服务的及CM的)./usr/share/cmf/ : 程序 ...
- Java多线程——中断机制
前言:在Java多线程中,中断一直围绕着我们,当我们阅读各种关于Java多线程的资料.书籍时,“中断”一词总是会出现,笔者对其的理解也是朦朦胧胧,因此非常有必要搞清楚Java多线程的中断机制. 1.J ...
- SQL SUM() 函数
SUM() 函数 SUM 函数返回数值列的总数(总额). SQL SUM() 语法 SELECT SUM(column_name) FROM table_name SQL SUM() 实例 我们拥有下 ...