[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。

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 }

 

posted @ 2018-02-04 19:29  Z-Y-Y-S  阅读(258)  评论(0编辑  收藏  举报