Bzoj2242 [SDOI2011]计算器

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 3611  Solved: 1400

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

HINT

 

Source

 

数学

喜闻乐见3 in 1

第一问,快速幂

第二问,扩展欧几里得

第三问,BSGS

提交上去秒WA,于是开始查BSGS的错(一般都会这么想吧),然而并没有发现错。

和黄学长的程序对拍BSGS,有那么几个数据不一样,调试无果,又找了一堆程序对拍,最后确定是黄学长写挂了233

最后发现是task2第48行,(LL)x*b写成了(LL)(x*b),大概是炸了

 

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #include<map>
  9 #define LL long long
 10 using namespace std;
 11 const int mxn=100010;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 16     return x*f;
 17 }
 18 int ksm(int a,int k,int p){
 19     int res=1;
 20     while(k){
 21         if(k&1)res=((LL)res*a%p);
 22         a=((LL)a*a%p);
 23         k>>=1;
 24     }
 25     return res;
 26 }
 27 void task1(int a,int k,int p){
 28     printf("%d\n",ksm(a,k,p));
 29 }
 30 int gcd(int a,int b){
 31     return (!b)?a:gcd(b,a%b);
 32 }
 33 void exgcd(int a,int b,int &x,int &y){
 34     if(!b){x=1;y=0;return;}
 35     exgcd(b,a%b,x,y);
 36     int tmp=x;x=y;y=tmp-a/b*y;
 37     return;
 38 }
 39 void task2(int a,int b,int p){
 40     int x,y;
 41     int tmp=gcd(a,p);
 42     if(b%tmp){
 43         printf("Orz, I cannot find x!\n");
 44         return;
 45     }
 46     b/=tmp;a/=tmp;p/=tmp;
 47     exgcd(a,p,x,y);
 48     x=(LL)x*b%p;
 49     while(x<0)x+=p;
 50     printf("%d\n",x);
 51     return;
 52 }
 53 map<int,int>mp;
 54 void task3(int a,int b,int p){
 55     if(a%p==0){
 56         if(b==0)printf("1\n");
 57         else printf("Orz, I cannot find x!\n");
 58         return;
 59     }
 60     mp.clear();
 61     int m=sqrt((double)p);
 62     int tmp=1;
 63     for(int i=0;i<m;i++){
 64         int now=((LL)tmp*b)%p;
 65         if(!mp[now])mp[now]=i;
 66         tmp=((LL)tmp*a)%p;
 67     }
 68     int res=1,ans,i;
 69     for(i=m;i<=p;i+=m){
 70         res=(LL)res*tmp%p;
 71         if(mp[res]){
 72             ans=i-mp[res];
 73             break;
 74         }
 75     }
 76     if(i>p){
 77         printf("Orz, I cannot find x!\n");
 78         return;
 79     }
 80     printf("%d\n",ans);
 81     return;
 82 }
 83 int y,z,p;
 84 int main(){
 85     int T,k;
 86     T=read();k=read();
 87     int y,z,p;
 88     while(T--){
 89         y=read();z=read();p=read();
 90         switch(k){
 91             case 1:{
 92                 task1(y,z,p);
 93                 break;
 94             }
 95             case 2:{
 96                 task2(y,z,p);
 97                 break;
 98             }
 99             case 3:{
100                 task3(y,z,p);
101                 break;
102             }
103         }
104     }
105     return 0;
106 }

 

本文为博主原创文章,转载请注明出处。
posted @ 2017-03-07 20:09  SilverNebula  阅读(126)  评论(0编辑  收藏  举报
AmazingCounters.com