1. 程式人生 > >BZOJ 3243 Clever Y

BZOJ 3243 Clever Y

more lol pmo .html zoj tdi end nav blog

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.

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