zoukankan      html  css  js  c++  java
  • EXGSBS模板

    EXBSGS模板

    我之前把有一处b和c弄反了,有点困...然后调了半天

    (exbsgs比excrt简单多了)

    a^{x}=c(mod\, \, b)x的最小正整数解

    原式子拆成a^{i*m-j}=c(mod ; b)

    在bsgs中,保证a,b互质,这样求出a^{j}(mod;b)的逆元挪过去才对

    但exbsgs中并不保证,所以必须不断取gcd(a,b)保证a,c互质

    p=frac{1}{prod_{k=1}^{n}gcd(k)}n为不断求gcd的总次数

    接下来式子变成了这样

    a^n/p cdot a^{x-n}=c/p(mod\, \, b/p)

    由于左边肯定和c互质,所以那部分直接挪右面求逆元再更新一下答案就行了

    剩下的a^{x-n}按BSGS思想移项,得a^{i*m}=ccdot a^{j}(mod;b)

    然后每次预处理a^{i*m}(mod;b)存进hash表/map,再在哈希表里找是否存在某一个值等于ccdot a^j(mod;b),找到了说明成立

     1 struct Hsh{
     2 #define maxn 400000
     3 int head[N1],to[M1],nxt[M1],val[M1],cte;
     4 void ins(int x,int w)
     5 {
     6     int u=x%maxn,j,v;
     7     for(j=head[u];j;j=nxt[j])
     8     {
     9         v=to[j];
    10         if(v==x) return;
    11     }
    12     cte++; to[cte]=x; nxt[cte]=head[u];
    13     head[u]=cte; val[cte]=w;
    14 }
    15 int find(int x)
    16 {
    17     int u=x%maxn,j,v;
    18     for(j=head[u];j;j=nxt[j])
    19     {
    20         v=to[j];
    21         if(v==x) return val[j];
    22     }
    23     return -1;
    24 }
    25 #undef maxn
    26 }h;
    27 
    28 int que[100],tl;
    29 int solve()
    30 {
    31     int g,i,sq;ll pw,ans=inf,now,tmp;
    32     if(A%B==0) return -1;
    33     A%=B; C%=B; tl=0;
    34     while(1)
    35     {
    36         g=gcd(A,B);
    37         if(g==1) break;
    38         if(C%g!=0) return -1;
    39         B/=g,C/=g; que[++tl]=A/g;
    40     }
    41     ll inv,invy;
    42     for(i=1;i<=tl;i++)
    43     {
    44         exgcd(que[i],B,inv,invy); inv=(inv%B+B)%B;
    45         C=inv*C%B;
    46     }
    47     if(C==1) return tl;
    48     sq=sqrt(B);
    49     for(pw=qpow(A,sq,B),now=1,i=1;(i-1)*sq<B;i++)
    50     {
    51         now=now*pw%B;
    52         h.ins(now,i);
    53     }
    54     for(now=C,i=0;i<sq;i++)
    55     {
    56         tmp=h.find(now);
    57         if(tmp!=-1) ans=min(ans,tmp*sq-i);
    58         now=now*A%B;
    59     }
    60     memset(&h,0,sizeof(h));
    61     if(ans==inf) return -1;
    62     return ans+tl;
    63 }
    64 
    65 int main()
    66 {
    67     int ans;
    68     while(scanf("%d%d%d",&A,&B,&C)&&A!=0){
    69         ans=solve();
    70         if(ans==-1) puts("No Solution");
    71         else printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    【Android 应用开发】 Android 相关代码规范 更新中 ...
    【IOS 开发】Object
    【Android 应用开发】 Android APK 反编译 混淆 反编译后重编译
    【IOS 开发】Object
    Unity3D 学习教程 14 C# 旋转镜头
    Unity3D 学习教程 13 C# 销毁炮弹
    Unity3D 学习教程 12 C# 发射炮弹
    Unity3D 学习教程 11 c#脚本控制摄像头
    Unity3D 学习教程 10 复制物体
    Unity3D 学习教程 9 旋转 放大 移动 物体
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9773936.html
Copyright © 2011-2022 走看看