1. 程式人生 > >BSGS學習筆記

BSGS學習筆記

printf std sca fin sqrt int true efi play

Problem

洛谷P3846 [TJOI2007]可愛的質數

Solution

\[ a^x\equiv b \mod p\a^{i*m-j}\equiv b \mod p\(a^m)^i\equiv b\times a^j \mod p \]

meet in middle

\(m=\sqrt p\)

將每個\(b\times a^j\)建表記錄下來

然後\((a^m)^i\)一路算過去

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int p;
map<int,bool>hs;
map<int,int>hs2;
int Pow(int x,int y){
    int re=1;
    while(y){
        if(y&1)re=(re*x)%p;
        y>>=1;
        x=(x*x)%p;
    }
    return re%p;
}
void format(int a,int b){
    hs.clear();hs2.clear();
    int hh=sqrt(p);b%=p;
    for(int j=0;j<=hh;++j){
        int pp=b*Pow(a,j)%p;
        hs[pp]=true,hs2[pp]=j;
    }
}
int fk(int a,int b){
    if(a==0)return b==0?1:-1;
    int hh=sqrt(p);
    int m=Pow(a,hh),d,j;
    for(int i=0;i<=hh;++i){
        d=Pow(m,i);
        if(hs[d]){
            j=hs2[d];
            if(j>=0&&i*hh-j>=0)
            return i*hh-j;
        }
    }
    return -1;
}
signed main(){
    int b,n;
    while(~scanf("%lld%lld%lld",&p,&b,&n)){
        format(b,n);
        int ans=fk(b,n);
        if(ans==-1)puts("no solution");
        else printf("%lld\n",ans);
    }
    return 0;
}
/*
5 2 1
5 2 2
5 2 3
5 2 4
5 3 1
5 3 2
5 3 3
5 3 4
5 4 1
5 4 2
5 4 3
5 4 4
12345701 2 1111111
1111111121 65537 1111111111

*/

BSGS學習筆記