BZOJ 3243 Clever Y

Description

Little Y finds there is a very interesting formula in mathematics:

XY mod Z = K

Given XYZ, we all know how to figure out K fast. However, given XZK, 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 XZK (0 ≤ XZK ≤ 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 }

 

posted @ 2018-02-04 15:25  Z-Y-Y-S  阅读(279)  评论(0编辑  收藏  举报