BSGS学习笔记

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

*/
posted @ 2019-05-17 09:35  The_KOG  阅读(...)  评论(...编辑  收藏