BZOJ 3243 Clever Y
阿新 • • 發佈:2018-02-04
more lol pmo .html zoj tdi end nav blog , Z, K (0 ≤ X, Z, K ≤ 109).
Input file ends with 3 zeros separated by spaces.
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 XInput 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 \neq 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\n"); 99 else printf("%lld\n",ans); 100 } 101 }
BZOJ 3243 Clever Y