您的位置:首页 > 其它

Bzoj2242 [SDOI2011]计算器

2017-03-07 20:09 357 查看
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

第一轮day1

 

数学

喜闻乐见3 in 1

第一问,快速幂

第二问,扩展欧几里得

第三问,BSGS

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

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

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

 

/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#define LL long long
using namespace std;
const int mxn=100010;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int ksm(int a,int k,int p){
int res=1;
while(k){
if(k&1)res=((LL)res*a%p);
a=((LL)a*a%p);
k>>=1;
}
return res;
}
void task1(int a,int k,int p){
printf("%d\n",ksm(a,k,p));
}
int gcd(int a,int b){
return (!b)?a:gcd(b,a%b);
}
void exgcd(int a,int b,int &x,int &y){
if(!b){x=1;y=0;return;}
exgcd(b,a%b,x,y);
int tmp=x;x=y;y=tmp-a/b*y;
return;
}
void task2(int a,int b,int p){
int x,y;
int tmp=gcd(a,p);
if(b%tmp){
printf("Orz, I cannot find x!\n");
return;
}
b/=tmp;a/=tmp;p/=tmp;
exgcd(a,p,x,y);
x=(LL)x*b%p;
while(x<0)x+=p;
printf("%d\n",x);
return;
}
map<int,int>mp;
void task3(int a,int b,int p){
if(a%p==0){
if(b==0)printf("1\n");
else printf("Orz, I cannot find x!\n");
return;
}
mp.clear();
int m=sqrt((double)p);
int tmp=1;
for(int i=0;i<m;i++){
int now=((LL)tmp*b)%p;
if(!mp[now])mp[now]=i;
tmp=((LL)tmp*a)%p;
}
int res=1,ans,i;
for(i=m;i<=p;i+=m){
res=(LL)res*tmp%p;
if(mp[res]){
ans=i-mp[res];
break;
}
}
if(i>p){
printf("Orz, I cannot find x!\n");
return;
}
printf("%d\n",ans);
return;
}
int y,z,p;
int main(){
int T,k;
T=read();k=read();
int y,z,p;
while(T--){
y=read();z=read();p=read();
switch(k){
case 1:{
task1(y,z,p);
break;
}
case 2:{
task2(y,z,p);
break;
}
case 3:{
task3(y,z,p);
break;
}
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: