列表

详情


NC50571. 计算器

描述

你被要求设计一个计算器完成以下三项任务:
  1. 给定y,z,p,计算的值;
  2. 给定y,z,p,计算满足的最小非负整数x;
  3. 给定y,z,p,计算满足的最小非负整数x。

输入描述

第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同);
以下T行每行包含三个正整数y,z,p,描述一个询问。

输出描述

对于每个询问,输出一行答案。
对于询问类型2和3,如果不存在满足条件的,则输出Orz,Icannotfindx!,注意逗号与I之间有一个空格。

示例1

输入:

3 1
2 1 3
2 2 3
2 3 3

输出:

2
1
2

示例2

输入:

3 2
2 1 3
2 2 3
2 3 3

输出:

2
1
0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 274ms, 内存消耗: 2512K, 提交时间: 2019-08-26 14:58:16

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ksm(ll x,ll y,ll p){
	ll res=1;
	while(y){
		if(y&1)
			res=res*x%p;
		x=x*x%p;
		y/=2;
	}
	return res;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1;
		y=0;
		return a;
	}
	ll d=exgcd(b,a%b,x,y);
	ll t=x;
	x=y;
	y=t-y*(a/b);
	return d;
}
ll bsgs(ll a,ll b,ll p){
	map<ll,ll>hash;
	hash.clear();
	b%=p;
	int t=(int)sqrt(p)+1;
	for(int j=0;j<t;j++){
		int val=(ll)b*ksm(a,j,p)%p;
		hash[val]=j;
	}
	a=ksm(a,t,p);
	if(a==0){
		if(b==0)
			return 1;
		else return -1;
	}
	for(int i=0;i<=t;i++){
		ll val=ksm(a,i,p);
		int j=hash.find(val)==hash.end()?-1:hash[val];
		if(j>=0&&j*t-j>=0)
			return i*t-j;
	}
	return -1;
}
int main(){
	int T,k;
	scanf("%d%d",&T,&k);
	while(T--){
		ll y,z,p;
		scanf("%lld%lld%lld",&y,&z,&p);
		if(k==1){
			printf("%lld\n",ksm(y,z,p));
		}
		else if(k==2){
			ll x=0,y1=0;
			ll d=exgcd(y,p,x,y1);
			//printf("%d\n",d);
			if(z%d!=0){
				printf("Orz, I cannot find x!\n");
				continue;
			}
			x=x*z/d;
			ll p1=p/d;
			x=(x%p1+p1)%p1;
			printf("%lld\n",x);
		}
		else{
			ll ans=bsgs(y,z,p);
			if(ans==-1)
				printf("Orz, I cannot find x!\n");
			else
				printf("%lld\n",ans);
		}
	}
}

C++11(clang++ 3.9) 解法, 执行用时: 117ms, 内存消耗: 3576K, 提交时间: 2020-10-10 14:48:45

#include<bits/stdc++.h>
using namespace std;
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int t,k,y,z,p,d,ax,ay,A,ph,prod;
map<int,int>ba;
bool euc(int a,int b,int &x,int &y){
	if(!b)
		if(z%a)return false;
		else x=1,y=0,d=a;
	else if(euc(b,a%b,y,x))y-=x*(a/b); 
		else return false;
	return true;
}int main(){
	for(scanf("%d%d",&t,&k);t--;){
		scanf("%d%d%d",&y,&z,&p);
		if(k==1){
			prod=1,y%=p;
			for(;z;z>>=1,y=1ll*y*y%p)
				if(z&1)prod=1ll*prod*y%p;
			printf("%d",prod);
		}else if(k==2){
			z%=p;
			if(euc(y,p,ax,ay))
				A=p/d,printf("%lld",((1ll*ax*z/d)%A+A)%A);
			else goto lose;
		}else if(k==3){
			if(z==1){
				putchar('0');
				goto end;
			}if(!(y%p)){
				if(z==0){
					putchar('1');
					goto end;
				}else goto lose;
			}ph=ceil(sqrt(p-1)),A=prod=1,ba.clear();
			for(int i=1;i<=ph;i++)
				prod=1ll*prod*y%p,ba[1ll*prod*z%p]=i;
			for(int i=1;i<=ph;i++){
				A=1ll*A*prod%p;
				if(ba[A]){
					printf("%d",i*ph-ba[A]);
					goto end;
				}
			}lose:printf("Orz, I cannot find x!");
		}end:putchar('\n');
	}return 0;
}

上一题