zoukankan      html  css  js  c++  java
  • POJ 3243 Clever Y | BSGS算法完全版

    题目:

    给你A,B,K

    求最小的x满足Ax=B (mod K)


    题解:

    如果A,C互质请参考上一篇博客

    将 Ax≡B(mod C) 看作是Ax+Cy=B方便叙述与处理.

    我们将方程一直除去A,C的最大公约数进行变形,最终使得A和C互质.

    将方程同除d1=gcd(A,C),得到B1=A/d1*Ax-1+C1y.有可能A和C1不互素,因此继续将方程同除d2=gcd(A,C1)得到B2=A2/d1d2*Ai-2+C2y.一直这样下去知道A和Ci互素.这里也能看出,若Bi不被gcd(A,Ci)整除则无解.

    最终得到Bn=An/d1d2...dn*Ax-n+Cny,并记D=An/d1d2...dn,易证明gcd(D,Cn)=1,因此存在D的逆元,可以将最后的式子变为A x-n≡BnD-1(mod Cn),此时就能求解了.


     

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cmath>
      5 typedef long long ll;
      6 using namespace std;
      7 ll x,z,k;
      8 ll Gcd(ll x,ll y)
      9 {
     10     return y==0?x:Gcd(y,x%y);
     11 }
     12 ll exGcd(ll a,ll b,ll &x,ll &y)
     13 {
     14     if (b==0) return x=1,y=0,a;
     15     ll r=exGcd(b,a%b,y,x);
     16     y-=a/b*x;
     17     return r;
     18 }
     19 ll inv(ll a,ll m)
     20 {
     21     ll x,y;
     22     exGcd(a,m,x,y);
     23     return (x%m+m)%m;
     24 }
     25 namespace Hash
     26 {
     27     const ll N=50000;
     28     const ll H=999979;
     29     struct adj
     30     {
     31     ll nxt,v,num,val;
     32     }e[N];
     33     ll  head[H],ecnt=0;
     34     void init()
     35     {
     36     ecnt=0;
     37     memset(head,0,sizeof(head));
     38     }
     39     void insert(ll x,ll val)
     40     {
     41     ll org=x;
     42     x%=H;
     43     for (int i=head[x];i;i=e[i].nxt)
     44     {
     45         if (e[i].num==org)
     46         {
     47         e[i].val=val;
     48         return ;
     49         }
     50     }
     51     e[++ecnt].num=org;
     52     e[ecnt].val=val;
     53     e[ecnt].nxt=head[x];
     54     head[x]=ecnt;
     55     }
     56     ll query(ll x)
     57     {
     58     ll org=x;
     59     x%=H;
     60     for (int i=head[x];i;i=e[i].nxt)
     61         if (e[i].num==org) return e[i].val;
     62     return -1;
     63     }
     64 }
     65 ll BSGS(ll a,ll b,ll c)
     66 {
     67     ll cnt=0,G,d=1;
     68     while ((G=Gcd(a,c))!=1)
     69     {
     70     if (b%G!=0) return -1;
     71     cnt++,b/=G,c/=G;
     72     d=d*(a/G)%c;
     73     }
     74     b=b*inv(d,c)%c;
     75     Hash::init();
     76     ll s=sqrt(c*1.0);
     77     ll p=1;
     78     for (int i=0;i<s;i++)
     79     {
     80     if (p==b) return i+cnt;
     81     Hash::insert(p*b%c,i);
     82     p=p*a%c;
     83     }
     84     ll q=p,t;
     85     for (int i=s;i-s+1<=c-1;i+=s)
     86     {
     87     t=Hash::query(q);
     88     if (t!=-1) return i-t+cnt;
     89     q=q*p%c;
     90     }
     91     return -1;
     92 }
     93 int check()
     94 {
     95     for (ll i=0,j=1;i<=10;i++)
     96     {
     97     if (j==k)
     98     {
     99         printf("%lld
    ",i);
    100         return 1;
    101     }
    102     j=j*x%z;
    103     }
    104     if (x==0)
    105     {
    106     puts("No Solution");
    107     return 1;
    108     }
    109     return 0;
    110 }
    111 int main()
    112 {
    113     while (scanf("%lld%lld%lld",&x,&z,&k) && x+z+k>0)
    114     {
    115     x%=z,k%=z;
    116     if (check()) continue;
    117     ll ans=BSGS(x,k,z);
    118     if (ans==-1) puts("No Solution");
    119     else printf("%lld
    ",ans);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    hdoj 2544 最短路径
    树状数组 hdoj1166
    并查集学习
    1402大数相乘 FFT算法学习!
    hdu1014
    动态规划 简单题dp
    迷宫路径
    简单的动态规划dp
    poj 3282 (bFS)
    背包问题,看不懂,啊!!!!!!!!dp
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7921715.html
Copyright © 2011-2022 走看看