【SDOI2011】计算器[数论 BSGS]
SDOI2011 计算器
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。
第一个要求直接快速幂
第二个要求因为保证P为质数 直接费马小定理求逆元然后*z
第三个就是BSGS模板
==打的时候1mol错 要注意该加括号的就加括号 不要图简便啥的不加 然后就long long
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define Abs(x) ((x)<0?-(x):(x))
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
const int N=10000+5,M=20000+5,INF=1e9+7,inf=0x3f3f3f3f;
int y,z,p;
template <class t>void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int qpow(int a,int b){
int res=1;
while(b){
if(b&1) res=(ll)a*res%p;
a=(ll)a*a%p,b>>=1;
}
return res;
}
map<int,int>hash;
int BSGS(){
hash.clear();y%=p,z%=p;
if(!y) return -1;
int t=(int)sqrt(p)+1;
for(int j=0,val;j<t;++j)
val=(ll)z*qpow(y,j)%p,hash[val]=j;
y=qpow(y,t);
if(!y) return !z?1:-1;
for(int i=0,val,j;i<=t;++i){
val=qpow(y,i);
j=hash.find(val)==hash.end()?-1:hash[val];
if(j>=0&&i*t-j>=0) return i*t-j;
}
return -1;
}
void work2(){
if(!(y%p)&&z%p) puts("Orz, I cannot find x!");
else printf("%lld\n",(ll)qpow(y,p-2)*z%p);
}
void work3(){
int ans=BSGS();
if(ans==-1) puts("Orz, I cannot find x!");
else printf("%d\n",ans);
}
int main(){
freopen("in.txt","r",stdin);
int T,K;rd(T),rd(K);
while(T--){
rd(y),rd(z),rd(p);
if(K==1) printf("%d\n",(qpow(y,z))%p);
else if(K==2) work2();
else work3();
}
return 0;
}