【模板】扩展BSGS板子 POJ3243 Clever Y
鉴于CQOI2018居然考了一道BSGS的板子题,就默默得又复习了一下BSGS以及又学了EXBSGS,CQOI那道题太板了,朴素BSGS,可以直接参考我以前的文章:POJ2417高次同余方程
这个HASH表的模板是直接抄的,,不会啊,,看来下一步是有必要学一下HASH表了。
EXBSGS的不同于朴素BSGS的地方是,EXBSGS的模数可以不受到一定要是质数的影响。可以是任何数。
令 d = gcd(A, C) , A = ad, B = bd, C = cd
则 ad ≡ bd (mod cd)
等价于 a ≡ b (mod c )
问题变成了求D * A^(x-cnt) ≡ B (mod C),因此我们先消除因子,不断地枚举r=gcd(a,c),然后b/=r,c/=r,base*=(a/r)(base是指的是大小步算法里面的大步块),然后将令x = i * m + j + cnt,cnt为消除的次数,方法就和朴素BSGS一样了。但是我们要考虑其x小于cnt的情况,于是,我们先要枚举cnt次,大约(log C)次,判断得到的是不是刚好等于B。
以下是code....
#include<map>
#include<cstdio>
#include<iostream>
#include<cmath>
typedef long long ll;
using namespace std;
ll gcd(ll a,ll b) { return !b?a:gcd(b,a%b); }
struct Hashmap
{
static const int Ha=999917,maxe=46340;
int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5];
int top,stk[maxe+5];
void clear() {E=0;while (top) lnk[stk[top--]]=0;}
void Add(int x,int y) {son[++E]=y;nxt[E]=lnk[x];w[E]=INT_MAX;lnk[x]=E;}
bool count(int y)
{
int x=y%Ha;
for (int j=lnk[x];j;j=nxt[j])
if (y==son[j]) return true;
return false;
}
int& operator [] (int y)
{
int x=y%Ha;
for (int j=lnk[x];j;j=nxt[j])
if (y==son[j]) return w[j];
Add(x,y);stk[++top]=x;return w[E];
}
};
Hashmap ma;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) { x=1; y=0; return a; }
ll r=exgcd(b,a%b,x,y);
ll tmp=x; x=y; y=tmp-(a/b)*y;
return r;
}
ll EXbsgs(ll a,ll b,ll c)
{
if(c==1) {if(!b) return a!=1; else return -1;}
if(b==1) {if(a) return 0; else return -1;}
if(a%c==0) {if(!b) return 1; else return -1;}
ll num=0,r,d=1;
while( (r=gcd(a,c))>1 )
{
if(b%r) return -1; ++num;
b/=r; c/=r; d=d*a/r%c;
}
for(ll i=0,now=1;i<num;i++,now=now*a%c)
if(now==b) return i;
ll bb=1;
ma.clear(); ll m=ceil(pow(c,0.5));
for(ll i=0;i<m;i++)
{
if(!ma.count(bb)) ma[bb]=i;
bb=bb*a%c;
}
ll x,y;
for(ll i=0;i<m;i++)
{
r=exgcd(d,c,x,y);
x=(x*b%c+c)%c;
if(ma.count(x)) return i*m+ma[x]+num;
d=d*bb%c;
}
return -1;
}
int main()
{
ll a,b,c,ans;
while(233)
{
scanf("%lld%lld%lld",&a,&c,&b);
if(a+b+c==0) return 0;
ans=EXbsgs(a,b,c);
ans==-1?printf("No Solution\n"):printf("%lld\n",ans);
}
}

浙公网安备 33010602011771号