[bzoj2242][SDOI2011][计算器] (Baby-Step-Giant-Step+快速幂+exgcd)
Description
你被要求设计一个计算器完成以下三项任务:
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)的最小非负整数。
Input
输入包含多组数据。
第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下行每行包含三个正整数y,z,p,描述一个询问。
Output
对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。
Sample Input
【样例输入1】
3 1
2 1 3
2 2 3
2 3 3
【样例输入2】
3 2
2 1 3
2 2 3
2 3 3
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
3 1
2 1 3
2 2 3
2 3 3
【样例输入2】
3 2
2 1 3
2 2 3
2 3 3
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
Sample Output
【样例输出1】
2
1
2
【样例输出2】
2
1
0
2
1
2
【样例输出2】
2
1
0
HINT
Source
#include <map> #include <math.h> #include <stdio.h> #define L long long #define inf ~0U>>1 #define dmin(a,b) ((a)<(b)?(a):(b)) template<class Type>inline void Rin(Type &x){ x=0;Type c=getchar(),f=1; for(;c<48||c>57;c=getchar()) if(c==45)f=-1; for(;c>47&&c<58;c=getchar()) x=(x<<1)+(x<<3)+c-48; x*=f; } std::map<int,int>mp; int T,Kd; struct Pep{ L fir,sec; Pep(L _=0,L __=0) : fir(_),sec(__) {} }; L gcd(L a,L b){ return b?gcd(b,a%b):a; } Pep exgcd(L a,L b){ if(!b)return Pep(1,0); Pep temp=exgcd(b,a%b); return Pep(temp.sec,temp.fir-a/b*temp.sec); } L frog1(L y,int p,L mo){ L res=1LL; while(p){ if(p&1)res=(res*y)%mo; y=(y*y)%mo; p>>=1; } return res; } void frog2(int a,int b,L p){ p=-p; int t=gcd(a,p); if(b%t){puts("Orz, I cannot find x!");return;} a/=t; b/=t; p/=t; Pep temp=exgcd(a,p); temp.fir=(L)(temp.fir*b)%p; while(temp.fir<0)temp.fir+=p; printf("%d\n",temp.fir); } void frog3(int A,int B,L p){ A%=p; if((!A) && (!B)){puts("1");return;} if((!A)){puts("Orz, I cannot find x!");return;} mp.clear(); L m=ceil(sqrt(p)),temp=1LL; mp[1]=m+1; for(L i=1;i<m;i++){ (temp*=A)%=p; if(!mp[temp])mp[temp]=i; } L D=frog1(A,p-m-1,p),ine=1LL; for(L k=0;k<m;k++){ int i=mp[B*ine%p]; if(i){ if(i==m+1)i=0; printf("%lld\n",k*m+i); return; } ine=ine*D%p; } puts("Orz, I cannot find x!"); } int main(){ Rin(T); Rin(Kd); while(T--){ int y,z,p; Rin(y),Rin(z),Rin(p); if(Kd==1)printf("%lld\n",frog1(y,z,p)); else if(Kd==2)frog2(y,z,p); else frog3(y,z,p); } return 0; }