[模板] BSGS
2024-09-03 04:33:27
BSGS是一种解决一类专门的问题的解法,主要是解决已知A, B, C,求X使得A^x = B (mod p)这一类问题。
解法很简单,先设x = i*m-j(m=ceil(sqrt(p))),然后进行变形,得到ai*m = b*aj (mod p)。
先枚举j (范围0-m) ,将 b*aj 存入hash表。再枚举i (范围1-m) ,从hash表中寻找第一个满足ai*m = b*aj (mod p)。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
map <ll,int> mp;
ll t,m,n,ans,now;
ll p,a,b;
bool flag;
ll qpow(ll a,ll b)
{
ll sum = ;
while(b)
{
if(b % == )
{
sum *= a;
}
a *= a;
sum %= p;
a %= p;
b >>= ;
}
return sum;
}
int main()
{
while(~scanf("%lld%lld%lld",&p,&a,&b))
{
if(a % p == )
{
printf("no solution\n");
continue;
}
mp.clear();
m = ceil(sqrt(p));
flag = false;
now = b % p;
mp[now] = ;
for(int i = ;i <= m;i++)
{
now = (now * a) % p;
mp[now] = i;
}
t = qpow(a,m);
now = ;
duke(i,,m)
{
now = (now * t) % p;
if(mp[now])
{
flag = true;
ans = i * m - mp[now];
printf("%lld\n",(ans % p + p) % p);
break;
}
}
if(!flag)
printf("no solution\n");
}
return ;
}
最新文章
- 规则引擎集成接口(八)Java接口实例
- Swing多线程
- 小生经验贴 --- adapter的数据更新
- Java数据库连接代码集合(转)
- Uri、UriMatcher、ContentUris详解
- MIT6.828 JOS系统 lab2
- vs发布项目webconfig替换语法
- IO模型、线程模型
- uni-app 在input获取焦点(弹出软键盘后收起软键盘),页面不下滑,留下下方空白
- 在线编辑器ACE Editor的使用
- NEST - 编写布尔查询
- 【深入Java虚拟机】一 JVM类加载过程
- 022 Spark shuffle过程
- oracle之 反向键索引
- JavaScript Promise迷你书(中文版)
- 手机浏览器的User-Agent汇总
- CentOS下MySQL的安装过程
- mysql忘记root用户密码重置密码的方式
- oracle 启动数据库与监听器
- 2 实现第一个Django网站 博客