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. Spring--quartz中cronExpression配置说明

    Spring--quartz中cronExpression Java代码   字段      允许值         允许的特殊字符 秒       0-59        , - * / 分     ...

  2. sql server 分组排序

    环境: sql server 2012 语法 select ROW_NUMBER() over(partition BY 分组字段 order by 排序字段),* as rowNums from 表 ...

  3. HDU1244:Max Sum Plus Plus Plus

    题目链接:Max Sum Plus Plus Plus 题意:在n个数中取m段数使得这m段数之和最大,段与段之间不能重叠 分析:见代码 //dp[i][j]表示前i个数取了j段的最大值 //状态转移: ...

  4. bzoj 1112: [POI2008]砖块Klo【对顶堆】

    priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...

  5. 二分+树状数组/线段树(区间更新) HDOJ 4339 Query

    题目传送门 题意:给两串字符串,操作1:替换其中一个字符串的某个位置的字符 操作2:查询从p开始相等的最长连续长度 分析:树状数组可以维护一个区间内公共长度(连续)的情况,查询时用二分查找最远的端点即 ...

  6. Android偏好设置(6)应用和监听各偏好参数

    Reading Preferences By default, all your app's preferences are saved to a file that's accessible fro ...

  7. iOS生成PDF的关键代码-备忘

    //此方法只是把当前页面的内容生成PDF并保存在沙盒中. //还需要做:把当前面没有显示的内容以分页的形式生成PDF,并把PDF读取并显示出来 //关于显示可以参考:念茜的博客 iOS开发笔记——PD ...

  8. SpringCloud开发学习总结(六)—— 结合注解的AOP示例

    面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP ...

  9. Spring @Resource、@Autowired、@Qualifier区别

    @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...

  10. 获取select里面option所有的值

    1.HTML结构 <select id="test"> <option value="option-1">option-1</op ...