bzoj 2242 [SDOI2011]计算器
2242: [SDOI2011]计算器
Time Limit: 10 Sec Memory Limit: 512 MBDescription
你被要求设计一个计算器完成以下三项任务:
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。
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
2
1
2
【样例输出2】
2
1
0
HINT
Source
第一项任务可以用快速幂求出;
第二项任务用费马小定理或扩展欧几里得求出;
第三项任务用BSGS(Baby Steps Giant Steps) 详见http://www.cnblogs.com/WQHui/p/7592513.html;
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<map> #include<cmath> using namespace std; long long n,m,y,z,p,x,ans,block; map <long long,int> mp; long long Fast_Power(long long a,long long b,long long MOD){ long long res=1; while(b>0){ if(b%2==1) res=res*a%MOD; a=a*a%MOD; b=b/2; } return res; } void solve1(){ for(int i=1;i<=n;i++){ scanf("%lld%lld%lld",&y,&z,&p); y=y%p; printf("%lld\n",Fast_Power(y,z,p)); } } void solve2(){ for(int i=1;i<=n;i++){ scanf("%lld%lld%lld",&y,&z,&p); y=y%p; z=z%p; if(y==0 && z!=0) printf("Orz, I cannot find x!\n"); else printf("%lld\n",z*Fast_Power(y,p-2,p)%p); } } void solve3(){ for(int i=1;i<=n;i++){ ans=-1; mp.clear(); scanf("%lld%lld%lld",&y,&z,&p); y=y%p; if(!y&&!z){ printf("1\n"); continue; } if(y==0){ printf("Orz, I cannot find x!\n"); continue; } block=ceil(sqrt(p)); long long num=z; for(int j=0;j<=block;j++){ mp[num]=j+1; num=num*y%p; } long long sum=Fast_Power(y,block,p); num=sum; for(int j=1;j<=block;j++){ if(mp[num%p]){ if(mp[num%p]==-1) ans=0; else ans=j*block-mp[num]+1; break; } num=num*sum%p; } if(ans==-1) printf("Orz, I cannot find x!\n"); else printf("%lld\n",ans); } } int main(){ scanf("%lld%lld",&n,&m); if(m==1){ solve1(); } if(m==2){ solve2(); } if(m==3){ solve3(); } }