• 数学:拓展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 }

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

  • 相关阅读:
    SQL Server Always on 日志收缩
    jq 获取某个元素是否鼠标悬停
    百度地图BMap实现在行政区域内做标注
    2021年终折腾总结
    ssr服务端渲染搭建
    windbg解决服务器cpu过高问题
    【工具】Java实现MD5算法
    【原创】Java创建对象与C++创建对象的比较
    【原创】C# 文件操作详解(二)FileInfo类
    【原创】JavaEE项目问题总结(1)
  • 原文地址:https://www.cnblogs.com/aininot260/p/9491650.html
Copyright © 2020-2023  润新知