http://www.lydsy.com/JudgeOnline/problem.php?id=2242
此题就是入门的模板题
分别用到了快速幂取模
利用扩展欧几里得算法计算线性同余方程
利用 Baby Step Giant Step 算法解高次同余方程
典型的模板题
我把第三个算法翻译成为宝宝一小步,巨人一大步算法
我也不知道为什么会有这种算法名字
要是我发明了什么算法一定以自己的名字加附上冠
BSGS算法模板
ll BSGS(ll a,ll b,ll p){
map<ll,ll> Hash;
Hash.clear();
b%=p;
ll t=(ll)sqrt(p)+1;
for(ll j=0;j<t;++j){
ll val=b*quickmod(a,j,p)%p;
Hash[val]=j;
}
a=quickmod(a,t,p);
if(a==0)
return b==0?1:-1;
for(ll i=0;i<=t;++i){
int val=quickmod(a,i,p);
ll j=Hash.find(val)==Hash.end()?-1:Hash[val];
if(j>=0&&i*t-j>=0)
return i*t-j;
}
return -1;
}
以及AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll quickmod(ll a,ll b,ll m){ll ans=1;while(b)
{if(b&1)ans=(ans*a)%m;b>>=1;a=a*a%m;}return ans;}
ll exgcd(ll a,ll b,ll &x,ll &y){if (b==0){x=1,y=0;
return a;}ll q=exgcd(b,a%b,y,x);y-=a/b*x;return q;}
ll BSGS(ll a,ll b,ll p){
map<ll,ll> Hash;
Hash.clear();
b%=p;
ll t=(ll)sqrt(p)+1;
for(ll j=0;j<t;++j){
ll val=b*quickmod(a,j,p)%p;
Hash[val]=j;
}
a=quickmod(a,t,p);
if(a==0)
return b==0?1:-1;
for(ll i=0;i<=t;++i){
int val=quickmod(a,i,p);
ll j=Hash.find(val)==Hash.end()?-1:Hash[val];
if(j>=0&&i*t-j>=0)
return i*t-j;
}
return -1;
}
int main(){
ll T,K,y,z,p,a,x;
cin>>T>>K;
if(K==1){
while(T--){
cin>>y>>z>>p;
cout<<quickmod(y,z,p)<<endl;
}
}
if(K==2){
while(T--){
cin>>y>>z>>p;
ll G=exgcd(y,p,x,a);
if(z%G!=0){
cout<<"Orz, I cannot find x!"<<endl;
continue;
}
x=z/G*x;
p/=G;
if(x>=0)
x%=p;
else{
while(x<0){
x+=p;
}
}
cout<<x<<endl;
}
}
if(K==3){
while(T--){
cin>>y>>z>>p;
ll ans=BSGS(y,z,p);
if(ans==-1){
cout<<"Orz, I cannot find x!"<<endl;
}
else
cout<<ans<<endl;
}
}
}