[SDOI2011]计算器
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
1.快速幂
2.拓展欧几里德解线性方程
3.BSGS
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 int MOD=250000; 9 lol hash[300001],id[300001]; 10 void insert(lol x,lol d) 11 { 12 lol pos=x%MOD; 13 while (1) 14 { 15 if (hash[pos]==-1||hash[pos]==x) 16 { 17 hash[pos]=x; 18 id[pos]=d; 19 return; 20 } 21 pos++; 22 if (pos>=MOD) pos-=MOD; 23 } 24 } 25 bool count(lol x) 26 { 27 lol pos=x%MOD; 28 while (1) 29 { 30 if (hash[pos]==-1) return 0; 31 if (hash[pos]==x) return 1; 32 pos++; 33 if (pos>=MOD) pos-=MOD; 34 } 35 } 36 lol query(lol x) 37 { 38 lol pos=x%MOD; 39 while (1) 40 { 41 if (hash[pos]==x) return id[pos]; 42 pos++; 43 if (pos>=MOD) pos-=MOD; 44 } 45 } 46 lol qpow(lol x,lol y,lol Mod) 47 { 48 lol res=1; 49 while (y) 50 { 51 if (y&1) res=res*x%Mod; 52 x=x*x%Mod; 53 y>>=1; 54 } 55 return res; 56 } 57 lol exgcd(lol a,lol b,lol &x,lol &y) 58 { 59 if (!b) 60 { 61 x=1;y=0; 62 return a; 63 } 64 lol d=exgcd(b,a%b,x,y); 65 lol t=x;x=y;y=t-a/b*y; 66 return d; 67 } 68 lol BSGS(lol a,lol b,lol Mod) 69 {lol i; 70 if (b==1) return 0; 71 if (a==0&&b!=0) return -1; 72 memset(hash,-1,sizeof(hash)); 73 memset(id,0,sizeof(id)); 74 lol tim=sqrt((double)Mod); 75 lol tmp=b%Mod; 76 for (i=0;i<=tim;i++) 77 { 78 insert(tmp,i); 79 tmp=tmp*a%Mod; 80 } 81 lol t=tmp=qpow(a,tim,Mod); 82 for (i=1;i<=tim;i++) 83 { 84 if (count(tmp)) 85 return i*tim-query(tmp); 86 tmp=tmp*t%Mod; 87 } 88 return -1; 89 } 90 int main() 91 {int T,k,i; 92 lol x,y,p,ans; 93 while (cin>>T>>k) 94 { 95 for (i=1;i<=T;i++) 96 { 97 scanf("%lld%lld%lld",&x,&y,&p); 98 if (k==1) 99 { 100 printf("%lld\n",qpow(x,y,p)); 101 } 102 else if (k==2) 103 { 104 lol a,b; 105 lol d=exgcd(x,p,a,b); 106 if (y%d) printf("Orz, I cannot find x!\n"); 107 else 108 { 109 lol t=y/d; 110 a=a*t; 111 d=p/d; 112 printf("%lld\n",(a%d+d)%d); 113 } 114 } 115 else if (k==3) 116 { 117 ans=BSGS(x%p,y%p,p); 118 if (ans==-1) printf("Orz, I cannot find x!\n"); 119 else printf("%lld\n",ans); 120 } 121 } 122 } 123 }