POJ 3243 Clever Y
Time Limit: 5000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
Little Y finds there is a very interesting formula in mathematics:
XY mod Z = K
Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?
Input
Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 10 9).
Input file ends with 3 zeros separated by spaces.
Input file ends with 3 zeros separated by spaces.
Output
For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible Y (0 ≤
Y <
Z). Otherwise output the minimum Y you find.
Sample Input
5 58 33
2 4 3
0 0 0
Sample Output
9
No Solution
Source
POJ Monthly--2007.07.08, Guo, Huayang
依旧是离散对数。
和POJ2417基本相同:
http://www.cnblogs.com/SilverNebula/p/5668380.html
不同之处是这道题的X Z K没有特殊限制,可能不是质数,传统的做法应该是不断转化式子直到gcd(a',n')==1 ,然后再BSGS
代码参照Orion_Rigel的题解http://blog.csdn.net/orion_rigel/article/details/51893151
然而套用了之前2417的代码,发现能AC
也是神奇
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define LL long long 7 using namespace std; 8 const int mop=100007; 9 const int mxn=100020; 10 int hash[mxn],hd[mxn],id[mxn],next[mxn],cnt; 11 12 LL gcd(LL a,LL b){ 13 return (b==0)?a:gcd(b,a%b); 14 } 15 void ins(LL x,LL y){ 16 int k=x%mop; 17 hash[++cnt]=x; 18 id[cnt]=y;next[cnt]=hd[k];hd[k]=cnt; 19 return; 20 } 21 LL find(LL x){ 22 int k=x%mop; 23 for(int i=hd[k];i;i=next[i]){ 24 if(hash[i]==x)return id[i]; 25 } 26 return -1; 27 } 28 LL BSGS(int a,int b,int n){ 29 memset(hd,0,sizeof hd); 30 cnt=0; 31 if(!b)return 0; 32 int m=sqrt(n),i,j; 33 LL x=1,p=1; 34 for(i=0;i<m;i++,p=p*a%n)ins(p*b%n,i); 35 for(LL i=m;;i+=m){ 36 x=x*p%n; 37 if((j=find(x))!=-1)return i-j; 38 if(i>n)break; 39 } 40 return -1; 41 } 42 int main(){ 43 int x,z,k; 44 while(scanf("%d%d%d",&x,&z,&k)!=EOF){ 45 if(!x && !z && !k)break; 46 int ans=BSGS(x,k,z); 47 if(ans==-1)printf("No Solution\n"); 48 else printf("%d\n",ans); 49 50 } 51 return 0; 52 }
本文为博主原创文章,转载请注明出处。