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 ≤ 109).
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
转载自:Navi
当模数 $c$ 不是质数的时候,显然不能直接使用 $BSGS$ 了,考虑它的扩展算法。
前提:同余性质。
令 $d = gcd(a, c)$ , $A = a cdot d,B = b cdot d, C = c cdot d$
则 $a cdot d equiv b cdot d pmod{c cdot d}$
等价于 $a equiv b pmod{c}$
因此我们可以先消除因子。
对于现在的问题 $(A cdot d)^x equiv B cdot d pmod{C cdot d}$ 当我们提出 $d = gcd(a, c)$ ($d eq 1$)后,原式化为 $A cdot (A cdot d)^{x-1} equiv B pmod{C}$ 。
即求 $D cdot A^{x-cnt} equiv B pmod{C}$ ,令 $x = i cdot r-j+cnt$ 。之后的做法就和 $BSGS$ 一样了。
值得注意的是因为这样求出来的解 $x geq cnt$ 的,但有可能存在解 $x < cnt$ ,所以一开始需要特判。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 int MOD=250000; 9 lol hash[300001],id[300001]; 10 lol gcd(lol a,lol b) 11 { 12 if (!b) return a; 13 return gcd(b,a%b); 14 } 15 void insert(lol x,lol d) 16 { 17 lol pos=x%MOD; 18 while (1) 19 { 20 if (hash[pos]==-1||hash[pos]==x) 21 { 22 hash[pos]=x; 23 id[pos]=d; 24 return; 25 } 26 pos++; 27 if (pos>=MOD) pos-=MOD; 28 } 29 } 30 bool count(lol x) 31 { 32 lol pos=x%MOD; 33 while (1) 34 { 35 if (hash[pos]==-1) return 0; 36 if (hash[pos]==x) return 1; 37 pos++; 38 if (pos>=MOD) pos-=MOD; 39 } 40 } 41 lol query(lol x) 42 { 43 lol pos=x%MOD; 44 while (1) 45 { 46 if (hash[pos]==x) return id[pos]; 47 pos++; 48 if (pos>=MOD) pos-=MOD; 49 } 50 } 51 lol qpow(lol x,lol y,lol Mod) 52 { 53 lol res=1; 54 while (y) 55 { 56 if (y&1) res=res*x%Mod; 57 x=x*x%Mod; 58 y>>=1; 59 } 60 return res; 61 } 62 lol exBSGS(lol a,lol b,lol Mod) 63 {lol i; 64 if (b==1) return 0; 65 memset(hash,-1,sizeof(hash)); 66 memset(id,0,sizeof(id)); 67 lol cnt=0,d=1,t; 68 while ((t=gcd(a,Mod))!=1) 69 { 70 if (b%t) return -1; 71 cnt++; 72 b/=t;Mod/=t; 73 d=d*(a/t)%Mod; 74 if (d==b) return cnt; 75 } 76 lol tim=ceil(sqrt((double)Mod)); 77 lol tmp=b%Mod; 78 for (i=0;i<=tim;i++) 79 { 80 insert(tmp,i); 81 tmp=tmp*a%Mod; 82 } 83 t=tmp=qpow(a,tim,Mod); 84 tmp=tmp*d%Mod; 85 for (i=1;i<=tim;i++) 86 { 87 if (count(tmp)) 88 return i*tim-query(tmp)+cnt; 89 tmp=tmp*t%Mod; 90 } 91 return -1; 92 } 93 int main() 94 {lol p,a,b,ans; 95 while (scanf("%lld%lld%lld",&a,&p,&b)) 96 { 97 if (p==0) return 0; 98 if ((ans=exBSGS(a,b,p))==-1) printf("No Solution "); 99 else printf("%lld ",ans); 100 } 101 }