【BZOJ 2242】 [SDOI2011]计算器

2242: [SDOI2011]计算器Time Limit:10 SecMemory Limit:512 MBSubmit:1474Solved:581[Submit][Status]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 12 1 32 2 32 3 3【样例输入2】3 22 1 32 2 32 3 3【数据规模和约定】对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。

Sample Output

【样例输出1】212【样例输出2】210

HINTSource

第一轮day1

快速幂+乘法逆元+BSGS

三个模板。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>#include <cmath>#define LL long long#include <map>using namespace std;map<LL,LL> mp;LL pow(LL a,LL x,LL p){LL base=a,ans=1;while (x){if (x&1LL) ans=(ans*base)%p;base=(base*base)%p;x>>=1LL;}return ans;}void log_mod(LL a,LL b,LL p){LL m=(LL)ceil(sqrt(p));mp.clear();mp[1]=0;LL now=1;for (int i=1;i<m;i++){now=(now*a)%p;if (!mp.count(now)) mp[now]=i;}LL ni=pow(a,p-m-1,p);bool f=false;for (int i=0;i<m;i++){if (mp.count(b)) {printf("%lld\n",m*i+mp[b]);f=true;break;}b=(b*ni)%p;}if (!f)printf("Orz, I cannot find x!\n");}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",pow(y,z,p));continue;}y%=p,z%=p;if (!y&&z){printf("Orz, I cannot find x!\n");continue;}if (k==2){if (!y) puts("0");elseprintf("%lld\n",pow(y,p-2,p)*z%p);}if (k==3){if (!y) puts("1");else log_mod(y,z,p);}}return 0;}

战胜困难,走出困境,成功就会属于你。

【BZOJ 2242】 [SDOI2011]计算器

相关文章:

你感兴趣的文章:

标签云: