2242: [sdoi2011] Calculator
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2077 Solved: 812
Description
You are asked to design a calculator to complete the following three tasks:
1. Given Y, Z, P, calculate the value of y ^ Z mod P;
2. Given Y, Z, P, calculate the minimum non-negative integer that satisfies XY ≡ Z (mod P;
3. Given Y, Z, P, calculate the minimum non-negative integer that satisfies y ^ x ≡ Z (mod P.
Input
The input contains multiple groups of data.
The first line contains two positive integers t, K representing the number of data groups and the query type (for all data in a test point, the query type is the same ).
Each line below contains three positive integers Y, Z, and P, which describe a query.
Output
Output a line of answers for each query. For query Types 2 and 3, if the conditions are not met, the output is "orz, I cannot find X !", Note that there is a space between comma and I.
Sample Input
[Example input 1]
3 12 1 32 2 32 3 3
[Example input 2]
3 22 1 32 2 32 3 3
[Data scale and Conventions]
For 100% of data, 1 <= Y, Z, P <= 10 ^ 9, is the prime number, 1 <= T <= 10.
Sample output
[Example output 1]
212
[Sample output 2]
2
1
0
Question:
1. Fast Power.
2. Extend Euclidean.
3. bsgs, everyone should .. I'm not sure.
No, you can read it here --> it's good to write!
Code:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<map>#include<algorithm>using namespace std;#define N 100100#define LL long longmap<LL,LL> hash;int in(){ int x=0; char ch=getchar(); while (ch<‘0‘ || ch>‘9‘) ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x;}LL qp(LL x,LL y,LL p){ LL z=1; while (y){ if (y&1) z=(z*x)%p; x=(x*x)%p; y>>=1; } return z;}void work1(int y,int z,int p){ printf("%lld\n",qp(y,z,p));}LL gcd(LL x,LL y){ if (!y) return x; return gcd(y,x%y);}void exgcd(LL a,LL b,LL &x,LL &y){ if (!b){ x=1,y=0; return; } exgcd(b,a%b,x,y); LL k=x; x=y; y=k-a/b*y;}void work2(int y,int z,int p){ LL w=gcd(y,p); if (z%w){ printf("Orz, I cannot find x!\n"); return; } LL x,k; exgcd(y,p,x,k); x=x*z/w; x=(x+p)%p; while (x<0) x+=p; printf("%lld\n",x);}void work3(int y,int z,int p){ y%=p,z%=p; hash.clear(); if (!y && !z){ printf("1\n"); return; } if (!y){ printf("Orz, I cannot find x!\n"); return; } LL pp=ceil(sqrt(p)),v=qp(y,p-pp-1,p),k=1; hash[1]=pp+1; for (LL i=1; i<=pp; i++){ k=(k*y)%p; if (!hash[k]) hash[k]=i; } LL ans=-1; for (LL i=0; i<pp; i++){ LL j=hash[z]; if (j){ if (j==pp+1) j=0; ans=(i*pp+j); break; } z=(z*v)%p; } if (ans==-1) printf("Orz, I cannot find x!\n"); else printf("%lld\n",ans);}int main(){ int T=in(),k=in(); while (T--){ int y=in(),z=in(),p=in(); if (k==1) work1(y,z,p); else if (k==2) work2(y,z,p); else work3(y,z,p); } return 0;}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.
[Fast Power] [Extended Euclidean] [bsgs] [sdoi 2011] [bzoj 2242] Calculator