http://www.lydsy.com/JudgeOnline/problem.php?id=2242 (题目链接)
题意
给出y,z,p。求:1.yz mod p;2.xy=z(mod p);3.yx=z(mod p)。
Solution
1.快速幂
2.exgcd
3.BSGS
细节
数学题就是细节多,具体看代码。
代码
// bzoj2242
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
map<int,int> mp;
LL power(LL a,LL b,LL c) {
LL res=1;
while (b) {
if (b&1) res=res*a%c;
b>>=1;a=a*a%c;
}
return res;
}
void exgcd(LL a,LL b,LL &d,LL &x,LL &y) {
if (b==0) {d=a;x=1;y=0;return;}
exgcd(b,a%b,d,y,x);
y-=a/b*x;
}
LL BSGS(LL a,LL b,LL p) { //求解a^x=b(mod p),p为素数,无解返回-1.
if (a%p==0 && b==0) return 1;
if (a%p==0) return -1;
mp.clear();mp[1]=0; //注意a^0=1
int m=ceil(sqrt(p)); //向上取整,避免漏解
LL inv=power(a,p-m-1,p),e=1; //inv为a^m的逆元,用费马小定理求
for (int i=1;i<m;i++) { //求e[i]数组
e=e*a%p;
if (!mp.count(e)) mp[e]=i;
}
for (int i=0;i<m;i++) { //枚举a^(im),a^(im+1),a^(im+2)~~~
if (mp.count(b)) return mp[b]+i*m; //一定要是mp.count(),因为mp[b]可能为0
else b=b*inv%p;
}
return -1;
}
int main() {
LL T,K,Y,Z,P;scanf("%lld%lld",&T,&K);
while (T--) {
scanf("%lld%lld%lld",&Y,&Z,&P);
if (K==1) printf("%lld
",power(Y,Z,P));
if (K==2) {
LL x,y,d;
exgcd(Y,P,d,x,y);
if (Z%d!=0) puts("Orz, I cannot find x!");
else printf("%lld
",((Z/d)*x%(P/d)+(P/d))%(P/d));
}
if (K==3) {
LL ans=BSGS(Y,Z,P);
if (ans==-1) puts("Orz, I cannot find x!");
else printf("%lld
",ans);
}
}
return 0;
}