BSGS 学习笔记

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

引理1,

\[a^{i\bmod\varphi(p)} \equiv a^i \pmod p \]

\(p\)为素数,即 \(a^i\) 在模 \(p\) 的意义下会出现循环节 (注: \(\varphi(p)\) 可能不是最小循环节)

因为 \(a^{p-1}\equiv 1\pmod p\),则 \(a^{k\times(p-1)} \equiv 1 \pmod p\)

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

\(a^{2k\times(p-1)}\)\(a^{-k\times (p-1)}\)\(p\) 意义下的逆元

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

\(a^{i-k(p-1)} \equiv a^{i} \pmod p\)

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

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

\(a^{i-k\times(p-1)} \equiv a^{i\mod\varphi(p)} \equiv a^{i} \pmod p\)

QED


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

考虑构造一个 \(m\),使得 \(m=\lceil\sqrt{C}\rceil\)

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

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

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

接着我们开始枚举 $ A^{k\times m}$ 中的 \(m\),则两次枚举出来的式子的两两组合正好可以得到所有 $a \in [1,x] $,若遇到两次枚举出来的值相等,则输出答案,退出循环。

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");
}
posted @ 2019-03-17 11:41  Kreap  阅读(156)  评论(0编辑  收藏  举报