当前位置: 首页 > news >正文

学习笔记——BSGS

众所周知,北上广深是中国非常一线的城市,北京是首都,地处……

正片开始!

一、BSGS基础算法

实现目标: A x ≡ B ( m o d P ) , ( gcd ⁡ ( P , A ) = 1 ) A^x\equiv B(\mod P),(\gcd(P,A)=1) AxB(modP),(gcd(P,A)=1)求最小的 x x x
很明显,如果暴力枚举,时间是 O ( P ) O(P) O(P)的,只要题目数据范围大,就死定了。愿意的人欢迎尝试(无100警告)
于是,考虑 ~  莫队
~~~~~~~~~~~~~~~~                 分块
~~~~~~~~~~~~~~~~                 BSGS
为什么我要提前两个?
因为BSGS本质就是分块!
简单讲解一下,就是将本来 P P P种情况,平均分成了$\sqrt p $份,对每份内进行预处理
不直观?好,那就用直观的式子吧!
令 x = k p − t \texttt{令}x=k\sqrt p-t x=kp t
即 A k p ≡ A t B ( m o d p ) \texttt{即}A^{k\sqrt p}\equiv A^tB (\mod p) Akp AtB(modp)

于是,找个哈希表维护一下后面的即可

IO::pin>>y>>z>>p;
gp_hash_table<int,int> ht;
int f,s;
bool flg;
ht.clear();
f=ceil(sqrt(p));
s=1;
flg=1;
for(int i=1; i<=f; i++)s=1ll*s*y%p,ht[1ll*z*s%p]=i;
for(int j=1,k=s; j<=f; j++) {if(ht[k]&&flg) {wt(((1ll*j*f-ht[k])%p+p)%p,'\n');flg=0;}k=(1ll*s*k)%p;}if(flg)puts("Orz, I cannot find x!");

附赠模板代码

#pragma GCC optimize(1,"inline","Ofast")
#pragma GCC optimize(2,"inline","Ofast")
#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
namespace IO {class input {private:bool isdigit(char c) {return ('0'<=c&&c<='9');}public:input operator>>(int &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(short &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(bool &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(long &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(long long &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(__int128 &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(unsigned int &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(unsigned short &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(unsigned long &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(unsigned long long &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(unsigned __int128 &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();if(!y)x=-x;return *this;}input operator>>(double &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=x*10+(c^48),c=getchar();if(!y)x=-x;if(!isdigit(c))if(c!='.')return *this;double z=1;while(isdigit(c))z/=10.,x=x+z*(c^48),getchar();return *this;}input operator>>(long double &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=x*10+(c^48),c=getchar();if(!y)x=-x;if(!isdigit(c))if(c!='.')return *this;double z=1;while(isdigit(c))z/=10.,x=x+z*(c^48),c=getchar();return *this;}input operator>>(float &x) {x=0;bool y=1;char c=getchar();while(!isdigit(c))y&=(c!='-'),c=getchar();while(isdigit(c))x=x*10+(c^48),c=getchar();if(!y)x=-x;if(!isdigit(c))if(c!='.')return *this;double z=1;while(isdigit(c))z/=10.,x=x+z*(c^48),c=getchar();return *this;}input operator>>(std::string &x) {char c=getchar();x.clear();while(!(c!=' '&&c!='\n'&&c!='	'&&c!=EOF&&c))c=getchar();while(c!=' '&&c!='\n'&&c!='	'&&c!=EOF&&c) {x.push_back(c);c=getchar();}return *this;}input operator>>(char *x) {char c=getchar();int cnt=0;while(!(c!=' '&&c!='\n'&&c!='	'&&c!=EOF&&c))c=getchar();while(c!=' '&&c!='\n'&&c!='	'&&c!=EOF&&c) {x[cnt++]=c;c=getchar();}return *this;}input operator>>(char x) {x=getchar();return *this;}} pin;
};
inline void wt(char ch) {putchar(ch);
}
template<class T>
inline void wt(T x) {static char ch[40];int p=0;if(x<0)putchar('-'),x=-x;doch[++p]=(x%10)^48,x/=10;while(x);while(p)putchar(ch[p--]);
}
template<class T,class... U>
inline void wt(T x,U ...t) {wt(x),wt(t...);
}
#define int long long
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define frep(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define lqrep(i,a,v) for(int i=hd[a],v=e[i].v;i>=i##end;i=e[i].nxt,v=e[i].v)
const int N=1e5+7;
main() {
}
//目前快速输出pout还未搞定哦

到此就结束了吗?

当然不是!!!!!!!!!!

如果没有 gcd ⁡ ( P , A ) = 1 \gcd(P,A)=1 gcd(P,A)=1的话,前面的一切都成了一纸空文
那该如何?
如果不需要的旅客们可以摆烂了,以下是扩展板

二、BSGS基础算法

不妨设 gcd ⁡ ( P , A ) = d \gcd(P,A)=d gcd(P,A)=d
A x ≡ B ( m o d P ) − > ( A ′ × d ) x ≡ B ′ × d ( m o d P ) − > ( A ′ × d ) x − 1 ≡ B ′ ∗ A ′ − 1 ( m o d P ) A^x\equiv B(\mod P)->\\(A'\times d)^x\equiv B'\times d(\mod P)->\\(A'\times d)^{x-1}\equiv B'*A'^{-1}(\mod P) AxB(modP)>(A×d)xB×d(modP)>(A×d)x1BA1(modP)
接着按上文求解即可

http://www.lryc.cn/news/178685.html

相关文章:

  • 【AI视野·今日NLP 自然语言处理论文速览 第四十期】Mon, 25 Sep 2023
  • Linux C/C++下收集指定域名的子域名信息(类似dnsmap实现)
  • linux-定时任务
  • 在Spring Boot项目中使用Redisson
  • JavaScript 函数柯里化
  • springboot实现ACL+RBAC权限体系
  • C++20协程示例
  • 【Verilog 教程】6.2Verilog任务
  • Spring修炼之路(1)基础入门
  • GANs学习记录
  • Flink-CDC——MySQL、SqlSqlServer、Oracle、达梦等数据库开启日志方法
  • linux设置tomcat redis开机自启动
  • 跨域问题讨论
  • ESP32设备通信-两个ESP32设备之间HTTP通信
  • 数据结构学习笔记——查找算法中的树形查找(平衡二叉树)
  • P1830 轰炸III
  • 大语言模型LLM知多少?
  • Redis命令行使用Lua脚本
  • HTML详细基础(三)表单控件
  • map和set的具体用法 【C++】
  • 聚合统一,SpringBoot实现全局响应和全局异常处理
  • 【C/C++笔试练习】——数组名和数组名、switch循环语句、数据在计算机中的存储顺序、字符串中找出连续最长的数字串、数组中出现次数超过一半的数字
  • 力扣每日一题(+日常水题|树型dp)
  • 使用perming加速训练可预测的模型
  • 【数据库】存储引擎InnoDB、MyISAM、关系型数据库和非关系型数据库、如何执行一条SQL等重点知识汇总
  • 车道线分割检测
  • 树莓集团又一力作,打造天府蜂巢成都直播产业园样板工程
  • ubuntu 软件包管理之二制作升级包
  • TCP/IP网络江湖——数据链路层的防御招式(数据链路层下篇:数据链路层的安全问题)
  • ios项目安装hermes-engine太慢问题