BZOJ2242 SDOI2011 计算器 快速幂+逆元+BSGS

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long

ll y,z,p,T,L;
map<ll,ll> table;
map<ll,ll>::iterator it;

ll Quick_Pow(ll x,ll y,ll p){
x%=p;
ll t=(y&1?x:1);

while(y>>=1){
x*=x,x%=p;
if(y&1) t*=x,t%=p;
}
return t;
}

void exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return;
}
exgcd(b,a%b,x,y);

ll t=x;
x=y,y=t-a/b*y;
}

ll Calc_inv(ll a,ll p){
ll x,y;
exgcd(a,p,x,y);
return (x+p)%p;
}

void Solve_Equation(ll x,ll y,ll p){
if(!(x%p)) cout << "Orz, I cannot find x!" << endl;
else cout << (Calc_inv(x,p)*y)%p << endl;
}

void BSGS(ll a,ll b,ll p){
a%=p,b%=p,table.clear();

if(!a){
if(!b) cout << 1 << endl;
else cout << "Orz, I cannot find x!" << endl;
return;
}

ll m=ceil(sqrt((double)p)),t=1,tmp=1,x,ans=-1;

for(int i=0;i<m;i++,t=t*a%p) table[t]=i;

for(int i=0;i<=m;i  ++){
x=Calc_inv(tmp,p),it=table.find(x*b%p);
if(it!=table.end()){
ans=i*m+it->second;
break;
}
tmp=tmp*t%p;
}

if(ans==-1) cout << "Orz, I cannot find x!" << endl;
else cout << ans << endl;
}

int main(){
cin >> T >> L;
while(T--){
cin >> y >> z >> p;
if(L==1) cout << Quick_Pow(y,z,p) << endl;
if(L==2) Solve_Equation(y,z,p);
if(L==3) BSGS(y,z,p);
}

return 0;
}
View Code

posted @ 2017-02-26 12:32  WDZRMPCBIT  阅读(98)  评论(0编辑  收藏  举报