BSGS和EXBSGS是OI中用于解决A^xΞB(mod C)的常用算法。

1.BSGS

BSGS用于A,C互质的情况。

令m=sqrt(C),此时x可表示为i*m+j。

式中i和j都<=sqrt(C)

原式Ax≡B(mode C) -->Ai*m * Aj≡B(mode C)

枚举Ai*m,此时Ai*m相当于系数。//O(sqrt(C))

现在我们可用exgcd/费马小定理求逆元算出Aj%C的值

通过预处理将A1~m存入map/哈希表。//O(1)//用map会多一个log

解决了。

时间复杂度O(sqrt(C)),思想类似meet_in_the_middle。

代码:

#include<map>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
ll fastpow(ll x,int y,int mod)
{
ll ret = 1ll;
while(y)
{
if(y&)ret=ret*x%mod;
x=x*x%mod;
y>>=;
}
return ret;
}
void ORZ(){printf("Orz, I cannot find x!\n");}
ll F2(ll y,int z,int p)
{
ll tmp = fastpow(y,p-,p);
tmp = tmp*z%p;
return tmp;
}
int hed[],cnt=;
struct EG
{
int to,w,nxt;
}e[];
void ae(int f,int t,int w)
{
e[++cnt].to = t;
e[cnt].w=w;
e[cnt].nxt = hed[f];
hed[f] = cnt;
}
int find(int x)
{
int now = x%;
for(int j=hed[now];j;j=e[j].nxt)
if(e[j].to==x)
return e[j].w;
return -;
}
void BSGS(ll y,int z,int p)
{
if(!y&&z){ORZ();return ;}
cnt=;
memset(hed,,sizeof(hed));cnt=;
ae(,,);
int m = (int)sqrt(p);
ll now = ;
for(int i=;i<=m;i++)
{
now = now*y%p;
if(find(now)==-)
{
ae(now%,now,i);
}
}
ll u = ;
for(int i=;i<=m+;i++)
{
ll tmp = F2(u,z,p);
ll ans = find(tmp);
if(~ans)
{
printf("%lld\n",(ans+i*m)%p);
return ;
}
u=u*now%p;
}
ORZ();
}
int T,K,y,z,p;
int main()
{
scanf("%d%d",&T,&K);
while(T--)
{
scanf("%d%d%d",&y,&z,&p);
y%=p;
if(K==)printf("%lld\n",fastpow(y,z,p));
else if(K==)
{
z%=p;
if(!y&&z){ORZ();continue;}
printf("%lld\n",F2(y,z,p));
}else
{
z%=p;
BSGS(y,z,p);
}
}
return ;
}

2.EXBSGS

EXBSGS用于解决C不一定是质数的问题。

对于方程Ax≡B(mode C)(gcd(A,C)!=1):

设d=gcd(A,C)。

如果B%d!=0的话,要么B==0,要么无解。

这时我们可以将三者同时/d,得到:

(A/d)*Ax-1≡ B/d (mode C/d)

此时A和C/d依然可能不互质(比如A=5,C=25)。

循环这个过程就可以啦。

我们最后得到的方程形式为:

(Ai/∏d)*Ax-i ≡ B/∏d(mode C/∏d)

其实就是D*Ax-i≡ B’(mode C’),然后套BSGS就好了。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
void ORZ()
{
printf("No Solution\n");
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=,y=;
return ;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
ll inv(ll a,ll b)
{
ll x,y;
exgcd(a,b,x,y);
return (x%b+b)%b;
}
ll gcd(ll x,ll y)
{
return y?gcd(y,x%y):x;
}
ll F2(ll y,ll z,ll p)
{
y%=p,z%=p;
ll ret = inv(y,p);
return ret*z%p;
}
int hed[],cnt;
struct EG
{
ll to,nxt,w;
}e[];
void ae(ll f,ll t,ll w)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
e[cnt].w = w;
hed[f] = cnt;
}
ll find(ll x)
{
for(int j=hed[x%];j;j=e[j].nxt)
if(e[j].to==x)
return e[j].w;
return -;
}
ll BSGS(ll y,ll z,ll p)
{
memset(hed,,sizeof(hed));cnt=;
ae(,,);
y%=p,z%=p;
if(!y&&z)
{
ORZ();
return -;
}
ll now = 1ll,m = (ll)sqrt(p);
for(int i=;i<=m;i++)
{
now=now*y%p;
if(find(now)==-)
ae(now%,now,i);
}
ll u = 1ll;
for(int i=;i<=m+;i++)
{
ll tmp = F2(u,z,p);
ll ans = find(tmp);
if(~ans)
return ans+i*m;
u=u*now%p;
}
ORZ();
return -;
}
void EXBSGS(ll y,ll z,ll p)
{
if(!y&&z){ORZ();return ;}
if(z==){printf("0\n");return ;}
ll d = gcd(y,p),cnt=,D=1ll;
while(d!=)
{
if(z%d){ORZ();return ;}
cnt++;
z/=d,p/=d;
D=D*(y/d)%p;
d=gcd(y,p);
if(D==z){printf("%lld\n",cnt);return ;}
}
ll ans = BSGS(y,z*inv(D,p)%p,p);
if(ans!=-)printf("%lld\n",(ans+cnt)%p);
}
ll y,z,p;
int main()
{
while(scanf("%lld%lld%lld",&y,&p,&z))
{
if(!y&&!z&&!p)break;
EXBSGS(y,z,p);
}
return ;
}

模板BSGS(SDOI2011计算器) 模板EXBSGS的更多相关文章

  1. bzoj 2242: [SDOI2011]计算器 BSGS+快速幂+扩展欧几里德

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 你被 ...

  2. BZOJ 2242: [SDOI2011]计算器( 快速幂 + 扩展欧几里德 + BSGS )

    没什么好说的... --------------------------------------------------------------------- #include<cstdio&g ...

  3. BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS

    BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS 题意: 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p, ...

  4. BZOJ2242 [SDOI2011]计算器 【BSGS】

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 4741  Solved: 1796 [Submit][Sta ...

  5. 【洛谷 P2485】 [SDOI2011]计算器 (BSGS)

    题目链接 第一问:快速幂 第二问:扩欧解线性同余方程 第三问:\(BSGS\) 三个模板 #include <cstdio> #include <cmath> #include ...

  6. 【BZOJ2242】[SDOI2011]计算器 BSGS

    [BZOJ2242][SDOI2011]计算器 Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ ...

  7. 【bzoj2242】: [SDOI2011]计算器 数论-快速幂-扩展欧几里得-BSGS

    [bzoj2242]: [SDOI2011]计算器 1.快速幂 2.扩展欧几里得(费马小定理) 3.BSGS /* http://www.cnblogs.com/karl07/ */ #include ...

  8. BZOJ 2242: [SDOI2011]计算器 [快速幂 BSGS]

    2242: [SDOI2011]计算器 题意:求\(a^b \mod p,\ ax \equiv b \mod p,\ a^x \equiv b \mod p\),p是质数 这种裸题我竟然WA了好多次 ...

  9. bzoj 2242 [SDOI2011]计算器 快速幂+扩展欧几里得+BSGS

    1:快速幂  2:exgcd  3:exbsgs,题里说是素数,但我打的普通bsgs就wa,exbsgs就A了...... (map就是慢)..... #include<cstdio> # ...

  10. P2485 [SDOI2011]计算器

    P2485 [SDOI2011]计算器 题目描述 你被要求设计一个计算器完成以下三项任务: 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最 ...

随机推荐

  1. EF7学习资料整理

    EntityFramework 7 开发纪录 http://www.cnblogs.com/xishuai/archive/2014/11/28/ef7-develop-note.html Entit ...

  2. HDU 5945 Fxx and game (DP+单调队列)

    题意:给定一个 x, k, t,你有两种操作,一种是 x - i (0 <= i <= t),另一种是 x / k  (x % k == 0).问你把x变成1需要的最少操作. 析:这肯定是 ...

  3. [App Store Connect帮助]九、衡量 App 表现(1)分析和报告概述

    App Store Connect 提供如下分析和报告,以衡量您 App 的表现并查看向您支付的最终付款. App 分析 通过 App Store 展示次数.产品页面查看次数.销售额.App 使用次数 ...

  4. Centos 下php安装配置xdebug扩展

    2018年05月02日 19:54:42 杨汉松 阅读数:44   1.下载安装xdebug 获取xdebug wget http://www.xdebug.org/files/xdebug-2.3. ...

  5. jenkins构建maven项目

    使用jenkins构建部署maven项目 因为一开始我们是自定义插件,所以构建项目的时候没有显示maven风格的项目.如果要想使用maven,我们这里必须得安装一下插件,我们在插件管理器中, 可以看到 ...

  6. _bzoj1070 [SCOI2007]修车【最小费用最大流】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1070 以后做网络流题目就是不能省内存... #include <cstdio> ...

  7. [ZPG TEST 114] 阿狸的英文名【水题】

    1.      阿狸的英文名 阿狸最近想起一个英文名,于是他在网上查了很多个名字.他发现一些名字可以由两个不同的名字各取一部分得来,例如John(约翰)的前缀 “John”和Robinson(鲁滨逊) ...

  8. 51nod 1133 不重叠的线段(贪心)

    1133 不重叠的线段  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠 ...

  9. 实现字符串的查找和替换 分类: c/c++ 2014-10-09 22:33 469人阅读 评论(0) 收藏

    在字符串中查找目标字符串并将其替换为指定字符串,返回替换的次数.接口为 int find_str_replace(char *&str,const char *find_str,const c ...

  10. Android 线程池系列教程(2)Thread,Runnable是基类及如何写Run方法

    Specifying the Code to Run on a Thread 上一课   下一课 1.This lesson teaches you to Define a Class that Im ...