【题目】
题目描述:
你被要求设计一个计算器完成以下三项任务:
- 给定 、 、 ,计算 的值;
- 给定 、 、 ,计算满足 的最小非负整数 ;
- 给定 、 、 ,计算满足 的最小非负整数 。
输入格式:
输入包含多组数据。
第一行包含两个正整数 、 ,分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下 行每行包含三个正整数 、 、 ,描述一个询问。
输出格式:
对于每个询问,输出一行答案。对于询问类型 和 ,如果不存在满足条件的 ,则输出 “Orz, I cannot find x!”,注意逗号与 “I” 之间有一个空格。
样例数据:
【样例 】
扫描二维码关注公众号,回复:
5801939 查看本文章
输入
3 1
2 1 3
2 2 3
2 3 3
输出
2
1
2
【样例 】
输入
3 2
2 1 3
2 2 3
2 3 3
输出
2
1
0
【样例 】
输入
4 3
2 1 3
2 2 3
2 3 3
2 4 3
输出
0
1
Orz, I cannot find x!
0
备注:
【数据范围】
对于
的数据,
;
对于
的数据,
;
对于
的数据,
;
对于
的数据,
,
为质数,
。
【分析】
一道简单题。
对于操作 ,用快速幂轻松解决。
对于操作 ,可以先计算出 在模 意义下的逆元,然后除过去就是答案,若逆元为 就无解。
对于操作 ,直接套 模板就可以了。
注意一下判无解就可以 掉这道题了。
【代码】
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<tr1/unordered_map>
#define ll long long
using namespace std;
using namespace tr1;
unordered_map<int,int>Hash;
int Power(ll a,ll b,int p)
{
ll ans=1;
for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;
return ans;
}
void exgcd(int a,int b,int &x,int &y)
{
if(!b) {x=1,y=0;return;}
exgcd(b,a%b,y,x),y-=a/b*x;
}
void BSGS(int a,int b,int p)
{
Hash.clear();a%=p,b%=p;
int i,now=b,t=ceil(sqrt(p));
for(i=0;i<t;++i)
Hash[now]=i,now=(ll)now*a%p;
now=1,a=Power(a,t,p);
if(!a) return (void)puts(b?"Orz, I cannot find x!":"1");
for(i=0;i<=t;++i)
{
int j=(Hash.find(now)==Hash.end())?-1:Hash[now];
if(j>=0&&i*t-j>=0) {printf("%d\n",i*t-j);return;}
now=(ll)now*a%p;
}
puts("Orz, I cannot find x!");
}
int main()
{
int a,b,p,x,y,T,type;
scanf("%d%d",&T,&type);
while(T--)
{
scanf("%d%d%d",&a,&b,&p);
if(type==1) printf("%d\n",Power(a,b,p));
if(type==2)
{
exgcd(a,p,x,y),x=(x+p)%p;
if(x) printf("%d\n",(ll)b*x%p);
else puts("Orz, I cannot find x!");
}
if(type==3) BSGS(a,b,p);
}
return 0;
}