你被要求设计一个计算器完成以下三项任务:
1、给定y,z,p,计算Y^Z Mod P 的值;
2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。
标签:
输入包含多组数据。
1 2 #include <iostream> 3 #include <cstdio> 4 #include <cmath> 5 #include <map> 6 #define ll long long 7 using namespace std; 8 ll y,z,p; 9 10 ll fast_pow(ll y,ll z,ll p) 11 { 12 ll ans=1; 13 while (z) 14 { 15 if (z&1) ans=ans*y%p; 16 y=y*y%p; 17 z>>=1; 18 } 19 return ans; 20 } 21 22 ll gcd(ll a,ll b) 23 {return b==0?a:gcd(b,a%b);} 24 25 void ex_gcd(ll a,ll b,ll &x,ll &y) 26 { 27 if (!b) {x=1;y=0;return;} 28 ex_gcd(b,a%b,x,y); 29 ll t=x; x=y; y=t-a/b*y; 30 } 31 32 void solve1() 33 { 34 printf("%lld\n",fast_pow(y,z,p)); 35 } 36 37 void solve2() 38 { 39 ll d=gcd(y,p); 40 if (z%d) {printf("Orz, I cannot find x!\n");return;} 41 y/=d; z/=d; 42 ll a,b; 43 ex_gcd(y,p,a,b); 44 a=a*z%p; 45 while (a<0) a+=p; 46 printf("%lld\n",a); 47 } 48 49 void solve3() 50 { 51 y%=p,z%=p; 52 if (!y && !z) {puts("1"); return;} 53 if (!y) {printf("Orz, I cannot find x!\n");return;} 54 map<ll,ll> mp; 55 mp.clear(); 56 ll m=ceil(sqrt(p)); 57 ll t=fast_pow(y,m,p),k=z%p;//直接m即可 58 for (int i=0;i<m;i++) 59 { 60 if (!mp[k]) if (i) mp[k]=i;//注意变量,及时订正。 61 else mp[k]=-1; 62 k=k*y%p; 63 } 64 k=1; 65 for (int i=0;i<m;i++) 66 { 67 if (mp[k])//注意!mp与mp的判断 68 { 69 if (mp[k]==-1) mp[k]=0; 70 printf("%lld\n",i*m-mp[k]); 71 return; 72 } 73 k=k*t%p; 74 } 75 printf("Orz, I cannot find x!\n");//各种傻 76 } 77 78 int main() 79 { 80 int T,t; 81 scanf("%d%d",&T,&t); 82 while (T--) 83 { 84 scanf("%lld%lld%lld",&y,&z,&p); 85 if (t==1) solve1(); 86 if (t==2) solve2(); 87 if (t==3) solve3(); 88 } 89 }
【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS
标签:
原文地址:http://www.cnblogs.com/DMoon/p/5225450.html