题目:https://www.acwing.com/problem/content/226/
题意:有一个计算器能完成三种功能
1、给定Y,Z,P,计算YZModPYZModP 的值;
2、给定Y,Z,P,计算满足xY≡Z(modP)xY≡Z(modP)的最小非负整数;
3、给定Y,Z,P,计算满足Yx≡Z(modP)Yx≡Z(modP)的最小非负整数。
思路:第一种很明显就是个快速幂取模,第二种,因为p是个质数,所以我们可以用快速幂取逆元来计算,第三种就是BSGS的板子
#include <cstdio> #include <cstring> #include <cmath> #include <map> #include <iostream> #include <algorithm> using namespace std; #define LL long long #define ll long long //快速幂求a^b LL power(LL a,LL b,LL n) { LL s=1; while(b) { if(b&1) s=(s*a)%n; a=(a*a)%n; b=b>>1; } return s; } ll work2(ll y,ll z,ll p)//xy=z mod p { if(y%p==0&&z!=0) return -1; return z*power(y,p-2,p)%p; } ll bsgs(ll a,ll b,ll p){ map<ll,ll> hash; hash.clear(); b%=p; ll t=(ll)sqrt(p)+1; for(int j=0;j<t;j++){ ll val = (ll)b*power(a,j,p)%p; hash[val]=j; } a=power(a,t,p); if(a==0) return b==0?1:-1; for(int i=0;i<=t;i++){ ll val = power(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 a,b,t,n; ll op; scanf("%lld%lld",&t,&op); for(int i=0;i<t;i++){ scanf("%lld%lld%lld",&a,&b,&n); if(op==1){ printf("%lld ",power(a,b,n)); } else if(op==2){ ll w=work2(a,b,n); if(w==-1) printf("Orz, I cannot find x! "); else printf("%lld ",w); } else if(op==3){ ll w=bsgs(a,b,n); if(w==-1) printf("Orz, I cannot find x! "); else printf("%lld ",w); } } return 0; }