BSGS(Baby Step Gaint Step)

用于求\(A^{x} \equiv B \pmod{C}\) 高次方程的最小正整数解x,其中C为素数


引理1:$a^{i\mod\varphi(p) } \equiv a^{i} $ (mod p) p为素数,即\(a^i\)在模p的意义下会出现循环节(注:\(\varphi(p)\)不是最小循环节)

证明:
因为$ a^{p-1} \equiv 1 $ (mod p) (费马小定理) ,则 \(a^{k*(p-1)} \equiv 1\) (mod p)

所以$ a^{2k * (p-1)} * a^{-k * (p-1)} \equiv 1 $ (mod p)

所以$ a^{2k * (p-1)} $ 为 \(a^{-k * (p-1)}\) mod p意义下的逆元

$ \frac{a^{i}}{a^{k * (p-1)}} \equiv a^{i} * a^{2k * (p-1)} \equiv a^{i} * 1 \equiv a^{i} $ (mod p)

即$ a^{i-k*(p-1)} \equiv a^{i} $ (mod p)

又因为$ i \bmod \varphi(p) = i-k*(p-1) $

且p为素数,\(i-k*(p-1)=i-k * \varphi(p)\)

则$ a^{i-k*(p-1)} \equiv a^{i\mod\varphi(p)} \equiv a^{i} $ (mod p)

证毕!


根据引理1我们可知只需要枚举至多\(\varphi(C)\)个数就能知道方程的解,若枚举完后发现无解,则整个方程无解

考虑构造一个m,使得\(m=ceil(\sqrt{C})\) (其中ceil()为向上取整函数)

\(x=k*m-q\),原方程转化为$ A^{k * m-q} \equiv B \pmod{p}$

继续得到 $ A^{k * m} \equiv B*A^{q} \pmod{p}$

BSGS流程:到了这一步,我们先考虑枚举\(B*A^{q}\)中的q,至多\(\sqrt{C}\)次,然后我们把得到的值存入一个Hash表中

接着我们开始枚举 $ A^{k * m}$ 中的m,则两次枚举出来的式子的两两组合正好可以得到所有$range \in [1,x] $(作者就是被这个地方卡了一万年QwQ),若遇到两次枚举出来的值相等,则输出答案,退出循环。

(注:作者写这题的时候运势不好,Hash写挂了,换成了map,效果不影响)

Code:

#include<stdio.h>
#include<math.h>
#include<map>
using namespace std;
#define ll long long
#define int ll
#define HASH_MOD 76799777LL

map<int,int> hash;

ll qpow(ll A,ll B,ll C){
    if(B==0) return 1;
    if(B==1) return A;
    ll t=qpow(A,B>>1,C);
    t=t*t%C;
    if(B&1) t=t*A%C;
    return t;
}
ll BSGS(ll A,ll B,ll C){
    const int sizes=ceil(sqrt(C));
    ll base=B%C;
    hash[base]=0;
    for(int i=1;i<=sizes;i++){
        base=base*A%C;
        hash[base]=i;
    }
    base=qpow(A,sizes,C);
    ll tmp=1;
    for(ll i=1;i<=sizes;i++){
        tmp=tmp*base%C;
        if(hash[tmp])
            return ((i*sizes-hash[tmp])%C+C)%C;
    }
    return -1;
}
ll P,B,N;
signed main(){
    scanf("%lld%lld%lld",&P,&B,&N);
    if(!(B%P)){
        printf("no solution\n");
        return 0;
    }
    ll ans=BSGS(B,N,P);
    if(ans!=-1) printf("%lld",ans);
    else printf("no solution");
}

转载于:https://www.cnblogs.com/wwlwQWQ/p/10546079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本项目是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。该系统主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的Java学习者,包含项目源码、数据库脚本、项目说明等,有论文参考,可以直接作为毕设使用。 后台框架采用SpringBoot,数据库使用MySQL,开发环境为JDK、IDEA、Tomcat。项目经过严格调试,确保可以运行。如果基础还行,可以在代码基础之上进行改动以实现更多功能。 该系统的功能主要包括商品管理、订单管理、用户管理等模块。在商品管理模块中,可以添加、修改、删除商品信息;在订单管理模块中,可以查看订单详情、处理订单状态;在用户管理模块中,可以注册、登录、修改个人信息等。此外,系统还提供了数据统计功能,可以对销售数据进行统计和分析。 技术实现方面,前端采用Vue框架进行开发,后端使用SpringBoot框架搭建服务端应用。数据库采用MySQL进行数据存储和管理。整个系统通过前后端分离的方式实现,提高了系统的可维护性和可扩展性。同时,系统还采用了一些流行的技术和工具,如MyBatis、JPA等进行数据访问和操作,以及Maven进行项目管理和构建。 总之,本系统是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。系统经过严格调试,确保可以运行。如果基础还行,可以在代码基础之上进行改动以实现更多功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值