# BZOJ2242 SDOI2011 计算器calc

（我不会打同余标记就用等于代替了、、）

y^x=z(mod p)

y^(k[sqrt(p)]+i)=z(mod p)

y^i=z/(y^k[sqrt(p)]) (mod p)

y^i=z*y^(k[sqrt(p)](p-2)) (mod p) （费马小定理）

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <queue>

#define ps system("pause")
#define message printf("*\n")
#define pb push_back
#define X first
#define Y second
#define PII pair<int,int>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)

typedef long long ll;

using namespace std;

int T,k;
ll y,z,p,te,ans,c;
map<ll,ll> app;

int main(){
cin >>T >>k;
while	(T--){
cin >>y >>z >>p;
app.clear();
switch	(k){
case	1:
te=y;ans=1;
while	(z){
if	(z&1)	ans=ans*te%p;
(te*=te)%=p;z/=2;
}
cout <<ans <<endl;
break;
case	2:
c=p-2;te=y;ans=1;
while	(c){
if	(c&1)	ans=ans*te%p;
(te*=te)%=p;c/=2;
}
ans=z*ans%p;
if	((ans*y%p)==(z%p))	cout <<ans <<endl;
else	puts("Orz, I cannot find x!");
break;
case	3:
if	(y%p==0){
puts("Orz, I cannot find x!");
break;
}
te=1;
rep(i,0,int(sqrt(p))){
app[te]=i+1;
te=te*y%p;
}
te=int(sqrt(p));
bool fd=false;
rep(k,0,p/te){
c=k*(p-2)*te;
ll cur=y,res=1;
while	(c){
if	(c&1)	res=res*cur%p;
(cur*=cur)%=p;c/=2;
}
res=res*z%p;
if	(app[res]){
fd=true;
cout <<k*te+app[res]-1 <<endl;
break;
}
}
if	(!fd)	puts("Orz, I cannot find x!");
break;
}
}
return	0;
}


posted @ 2013-06-12 16:11  JS_Shining  阅读(1087)  评论(0编辑  收藏  举报