zoukankan      html  css  js  c++  java
  • 数学:拓展BSGS

    当C不是素数的时候,之前介绍的BSGS就行不通了,需要用到拓展BSGS算法

    方法转自https://blog.csdn.net/zzkksunboy/article/details/73162229

    典型例题是POJ3243

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 using namespace std;
     5 struct Hashmap
     6 {
     7     static const int Ha=999917,maxe=46340;
     8     int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5];
     9     int top,stk[maxe+5];
    10     void clear() {E=0;while (top) lnk[stk[top--]]=0;}
    11     void Add(int x,int y) {son[++E]=y;nxt[E]=lnk[x];w[E]=0X7fffffff;lnk[x]=E;}
    12     bool count(int y)
    13     {
    14         int x=y%Ha;
    15         for (int j=lnk[x];j;j=nxt[j])
    16             if (y==son[j]) return true;
    17         return false;
    18     }
    19     int& operator [] (int y)
    20     {
    21         int x=y%Ha;
    22         for (int j=lnk[x];j;j=nxt[j])
    23             if (y==son[j]) return w[j];
    24         Add(x,y);stk[++top]=x;return w[E];
    25     }
    26 }f;
    27 int gcd(int a,int b)
    28 {
    29     return b==0?a:gcd(b,a%b);
    30 }
    31 int exgcd(int a,int b,int &x,int &y)
    32 {
    33     if(b==0) {x=1;y=0;return a;}
    34     int r=exgcd(b,a%b,x,y);
    35     int t=x;x=y;y=t-a/b*y;
    36     return r;
    37 }
    38 int exBSGS(int A,int B,int C)
    39 {
    40     if(C==1) if(B==0) return A!=1; else return -1;
    41     if(B==1) if(A!=0) return 0; else return -1;
    42     if(A%C==0) if(B==0) return 1; else return -1;
    43     int r,D=1,num=0;
    44     while((r=gcd(A,C))>1)
    45     {
    46         if(B%r) return -1;
    47         num++;
    48         B/=r;C/=r;D=((long long)D*A/r)%C;
    49     }
    50     for(int i=0,tmp=1;i<num;i++,tmp=((long long)tmp*A)%C)
    51         if(tmp==B) return i;
    52     int m=ceil(sqrt(C)),Base=1;f.clear();
    53     for(int i=0;i<=m-1;i++)
    54     {
    55         f[Base]=min(f[Base],i);
    56         Base=((long long)Base*A)%C;
    57     }
    58     for(int i=0;i<=m-1;i++)
    59     {
    60         int x,y,r=exgcd(D,C,x,y);
    61         x=((long long)x*B%C+C)%C;
    62         if(f.count(x)) return i*m+f[x]+num;
    63         D=((long long)D*Base)%C;
    64     }
    65     return -1;
    66 }
    67 int main()
    68 {
    69     int A,B,C;
    70     while(scanf("%d%d%d",&A,&C,&B)==3)
    71     {
    72         if(!A&&!B&&!C) break;
    73         int ans=exBSGS(A,B,C);
    74         if(ans==-1) printf("No Solution
    ");
    75         else printf("%d
    ",ans);
    76     }
    77     return 0;
    78 }

    给哈希好评,哪天好好整理一下

  • 相关阅读:
    【python-leetcode107-树的宽度遍历】二叉树的层次遍历Ⅱ
    Spring依赖
    Dubbo依赖
    免费内网穿透
    Oracle分析函数Over()
    测压工具
    编译器版本
    修改gridfilters.js源码,往后台多传递一个参数,并设置NumericFilter、StringFilter默认提示信息
    网站10分钟不操作会话退出
    win10彻底关闭windows defender,解决无故占用大量CPU问题
  • 原文地址:https://www.cnblogs.com/aininot260/p/9491650.html
Copyright © 2011-2022 走看看