您的位置:首页 > 其它

bzoj2242【sdoi2011】计算器

2015-04-13 16:39 246 查看

2242: [SDOI2011]计算器

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1700  Solved: 660

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

Sample Output

【样例输出1】

2

1

2

【样例输出2】

2

1

0

HINT

Source

第一轮day1

题解:

① 快速幂。

② 乘法逆元。费马小定理:若p是质数,且a和p互质,则a^(p-1)%p=1。所以a的乘法逆元为a^(p-2)。所以最终结果为a^(p-2)*z%p。

③ BSGS算法。先把x=i*m+j,其中m=ceil(sqrt(p))。这样原式就变为y^(i*m+j)=z(mod p),再变为y^j=z*y^(-m*i) (mod p)。先循环j=0-(p-1),把(y^j,j)加入hash表中。然后我们再枚举等号右边,从hash表中找看看有没有,有的话就得到了一组i j,x=i*m+j,得到的这个就是正确解。y^(-m*i)相当于1/(y^(m*i)),这时候我们就要求逆元。

代码:

<span style="font-size:18px;">#include<iostream>
#include<math.h>
#include<map>
#include<cstdio>
#define LL long long
using namespace std;
map<LL,LL> mp;
LL power(LL y,LL x,LL p)
{
LL tmp,ans;
if (x==0) return 1;
if (x==1) return(y%p);
tmp=power(y,x/2,p);
ans=tmp*tmp%p;
if (x%2==1) ans=ans*y%p;
return ans;
}
void bsgs(LL a,LL b,LL p)
{
LL m=(LL)ceil(sqrt(p));
LL now,tmp,x;
mp.clear();
mp[1]=0;
now=1;
for (int i=1; i<m; i++)
{
now=(now*a)%p;
if (!mp.count(now)) mp[now]=i;
}
tmp=power(a,p-m-1,p);
x=b;
bool flag=false;
for (int i=0; i<m; i++)
{
if (mp.count(x))
{
printf("%lld\n",m*i+mp[x]);
flag=true;
break;
}
x=(x*tmp)%p;
}
if (!flag) printf("Orz, I cannot find x!\n");
}
int main()
{
int i,t,k;
LL y,z,p;
scanf("%d%d",&t,&k);
for (i=1; i<=t; i++)
{
scanf("%lld%lld%lld",&y,&z,&p);
if (k==1)
{
printf("%lld\n",power(y,z,p));
continue;
}
y%=p;
z%=p;
if (!y&&z)
{
printf("Orz, I cannot find x!\n");
continue;
}
if (k==2)
{
if (!y) printf("%d\n",0);
else printf("%lld\n",power(y,p-2,p)*z%p);
}
if (k==3)
{
if (!y) printf("%d\n",1);
else bsgs(y,z,p);
}
}
return 0;
}
//Written by aap</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: