bzoj2242【sdoi2011】计算器
2015-04-13 16:39
246 查看
2242: [SDOI2011]计算器
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 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>
相关文章推荐
- BZOJ 2242 [SDOI2011]计算器 BSGS+高速幂+EXGCD
- bzoj 2242: [SDOI2011]计算器
- 【BZOJ 2242】 [SDOI2011]计算器
- BZOJ 2242 [SDOI2011]计算器 BSGS+快速幂+EXGCD
- BZOJ 2242 SDOI2011 计算器 快速幂+扩展欧几里得+BSGS
- [原博客] BZOJ 2242 [SDOI2011] 计算器
- 【BZOJ 2242】[SDOI2011]计算器
- BZOJ2242 SDOI2011 计算器calc
- [bzoj2242][SDOI2011]计算器
- BZOJ 2242 [SDOI2011] 计算器
- 【数论】【快速幂】【扩展欧几里得】【BSGS算法】bzoj2242 [SDOI2011]计算器
- 【bzoj2242】【SDOI2011】【计算器】
- bzoj 2242 [SDOI2011]计算器(数论知识)
- BZOJ2242 [SDOI2011]计算器
- bzoj 2242: [SDOI2011]计算器
- Bzoj 2242: [SDOI2011]计算器(BSGS)
- BZOJ2242 SDOI2011 计算器
- 【bzoj2242】[SDOI2011]计算器 数论相关(快速幂+扩展欧几里得+BSGS)
- bzoj2242 : [SDOI2011]计算器 [BSGS算法]
- BZOJ-2242-计算器-SDOI2011-BSGS