Problem 2242. -- [SDOI2011]计算器

题意

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser   autointLogout 捐赠本站
Problem 2242. -- [SDOI2011]计算器

2242: [SDOI2011]计算器

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 6231  Solved: 2448
[Submit][Status][Discuss]

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,P为质数,1<=T<=10。

Sample Output

【样例输出1】
2
1
2
【样例输出2】
2
1
0

HINT

Source

[Submit][Status][Discuss]

HOME Back

分析

数学题杂糅。

  1. 快速幂
  2. exgcd
  3. bsgs

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
    while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;

int ksm(int a,int b,int p){
	int ans=1%p;
	a%=p,b%=p-1;
	for(;b;a=(ll)a*a%p,b>>=1)
		if(b&1) ans=(ll)ans*a%p;
	return ans;
}
int exgcd(int a,int b,int&x,int&y){
	if(!b) return x=1,y=0,a;
	int d=exgcd(b,a%b,y,x);
	return y-=a/b*x,d;
}
int bsgs(int a,int b,int p){
	std::map<int,int> H;
	b%=p;
	int t=sqrt(p)+1;
	for(int i=0;i<t;++i) H[(ll)b*ksm(a,i,p)%p]=i;
	a=ksm(a,t,p);
	if(!a) return b?-1:1;
	for(int i=0,val,j;i<=t;++i){
		val=ksm(a,i,p),j=H.find(val)==H.end()?-1:H[val];
		if(j>=0&&i*t>=j) return i*t-j;
	}
	return -1;
}
int main(){
//	freopen(".in","r",stdin),freopen(".out","w",stdout);
	int t=read<int>(),k=read<int>();
	for(int y,z,p;t--;){
		read(y),read(z),read(p);
		if(k==1) printf("%d
",ksm(y,z,p));
		else if(k==2){
			int x,t,d=exgcd(y,p,x,t);
			if(z%d) puts("Orz, I cannot find x!");
			else printf("%lld
",((ll)x*z/d%p+p)%p);
		}
		else{
			int ans=bsgs(y,z,p);
			if(ans==-1) puts("Orz, I cannot find x!");
			else printf("%d
",ans);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/autoint/p/10650334.html