【BZOJ2242】【SDOI2011】计算器

Description

1、给定y、z、p，计算y^z mod p 的值；

2、给定y、z、p，计算满足xy ≡z(mod p)的最小非负整数x；

3、给定y、z、p，计算满足y^x ≡z(mod p)的最小非负整数x。

3 1
2 1 3
2 2 3
2 3 3

2
1
2

3 2
2 1 3
2 2 3
2 3 3

2
1
0

4 3
2 1 3
2 2 3
2 3 3
2 4 3

Sample Output#3

0
1
Orz, I cannot find x!
0

Code

#include <stdio.h>
#include <math.h>
#include <map>
#define R register
#define ll long long
R int x; R bool f; R char c;
for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<1)+(x<<3)+c-'0');
return f?-x:x;
}
int T,tp,y,z,p;
std::map<int,int> mp;
inline int pw(int x,int k,int p){
R int res=1;
for (; k; k>>=1,x=(ll)x*x%p) if (k&1) res=(ll)res*x%p;
return res;
}
inline void bsgs(int y,int z,int p){
if (y==0&&z==0) return (void)(puts("1"));
if (y==0) return (void)(puts("Orz, I cannot find x!"));
R int m=sqrt(p)+0.5;mp.clear();R int tmp=0;for (R int i=0; i<=m; ++i){
if (i==0) {tmp=z%p; mp[tmp]=0; continue;}
tmp=(ll)tmp*y%p;
mp[tmp]=i;
}R int t=pw(y,m,p);tmp=1;
for (R int i=1; i<=m; ++i){
tmp=(ll)tmp*t%p;
if (mp.count(tmp)){
R ll ans=((ll)i*m)-mp[tmp];
ans=(ans%p+p)%p;
printf("%lld\n",ans);
return;
}
}puts("Orz, I cannot find x!");return;
}
int main(){
while(T--){
if (tp==1) printf("%d\n",pw(y,z,p));
else if (tp==2){
z%=p;if (y==0&&z!=0) puts("Orz, I cannot find x!");
else printf("%lld\n",(ll)z*pw(y,p-2,p)%p);
}else bsgs(y,z,p);
}
}

posted @ 2017-12-26 09:14  Melacau  阅读(246)  评论(0编辑  收藏  举报