BSGS & exBSGS

BSGS 

BSGS 用于当gcd(A,p)=1时,求方程的解。

由费马定理可知,当gcd(A,p)=1,且p为素数时,有所以得到

,x=am-b,,得到

通过枚举用hash维护任意一侧,再枚举另一侧,判断是否在hash,若在则答案为am-b。

例:poj 2417 Discrete Logging

#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
using namespace std;
long long quick(long long a,long long b,long long p);
int main()
{
  int i,f;
  long long s,t,A,B,p,m;
  while(~scanf("%lld%lld%lld",&p,&A,&B))
  {
    map<long long,long long> lmapl;
    f=0;m=ceil(sqrt(p));
    for(i=1;i<=m;i++)
    {
      B=B*A%p;
      lmapl[B]=i;
    }
    t=quick(A,m,p);
    for(i=1,s=1;i<=m;i++)
    {
      s=s*t%p;
      if(lmapl[s])
      {
       printf("%lld\n",i*m-lmapl[s]);
       f=1;
       break;
      }
    }
    if(!f) printf("no solution\n");
  }
  return 0;
}
long long quick(long long a,long long b,long long p)
{
  long long ans=1;
  while(b)
  {
    if(b&1) ans=ans*a%p;
    b>>=1;
    a=a*a%p;
  }
  return ans%p;
}
View Code

exBSGS

BSGS只能解决gcd(A,p)=1的情况,而通过exBSGS可以解决更一般的情况(不互质的情况)。

,得到,令d=gcd(A,p),通过同余定理可以得到(如果B%d!=0,则无解),通过这种方式一直往下迭代,直到 d=1 ,此时得到

 ,k为迭代次数,得到再通过BSGS求解,最后答案加上k。

int exbsgs(int a,int b,int p)
{
    if (b==1||p==1)return 0;     //特殊情况,x=0时最小解
    int g=gcd(a,p),k=0,na=1;
    while (g>1)
    {
        if (b%g!=0)return -1;    //无法整除则无解
        k++;b/=g;p/=g;na=na*(a/g)%p;
        if (na==b)return k;   //na=b说明前面的a的次数为0,只需要返回k
        g=gcd(a,p); 
    }
    int f=bsgs(a,b*inv(na,p)%p,p);
    if (f==-1)return -1;
    return f+k;
}

 

例:poj 3243  Clever Y

#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
#include<cstring>
using namespace std;
struct HashTable
{
  static const int MOD=99901,MAXN=200005;
  long long dat[MAXN],nxt[MAXN],head[MAXN],id[MAXN],cnt;
  void clear() 
  {
    memset(head,-1,sizeof(head));
    memset(nxt,0,sizeof(nxt));
    cnt=0;
  }
  void insert(long long x, long long y)
  {
    long long tmp=x%MOD;
    for(int i=head[tmp];i!=-1;i=nxt[i]) 
      if(dat[i]==x) 
       {
         id[i]=y; 
         return;
       }
    dat[++cnt]=x;id[cnt]=y;
    nxt[cnt]=head[tmp];head[tmp]=cnt;
  }
  long long query(long long x)
  {
    long long tmp=x%MOD;
    for(int i=head[tmp];i!=-1;i=nxt[i]) 
    {
      if(dat[i]==x) 
        return id[i];
    }
    return -1;
  }
}Hash;
long long quick(long long a,long long b,long long p);
long long bsgs(long long a,long long b,long long p,long long f);
long long exbsgs(long long a,long long b,long long p);
long long gcd(long long x,long long y);
int main()
{
  long long a,p,b,ans;
  while(scanf("%lld%lld%lld",&a,&p,&b))
  {
    if(!a&&!p&&!b) break;
    ans=exbsgs(a,b,p);
    if(ans!=-1) printf("%lld\n",ans);
    else printf("No Solution\n");
  }
  return 0;
}
long long gcd(long long x,long long y)
{return y?gcd(y,x%y):x;}
long long quick(long long a,long long b,long long p)
{
  long long ans=1;
  while(b)
  {
    if(b&1) ans=ans*a%p;
    b>>=1;
    a=a*a%p;
  }
  return ans;
}
long long exbsgs(long long a,long long b,long long p)
{
  Hash.clear();
  if(b==1||p==1) return 0;
  long long d=gcd(a,p),k=0,na=1,ans;
  while(d!=1)
  {
   if(b%d) return -1;
   k++;b/=d;p/=d;na=na*(a/d)%p;
   if(na==b) return k;
   d=gcd(a,p);
  }
  ans=bsgs(a,b,p,na);
  return ans==-1?-1:ans+k;
}
long long bsgs(long long a,long long b,long long p,long long f)
{
  int i;
  long long m=ceil(sqrt(p)),s,t;
  for(i=1;i<=m;i++)
  {
    b=b*a%p;
    Hash.insert(b, i);
  }
  t=quick(a,m,p);
  for(i=1,s=f;i<=m;i++)
  {
   s=s*t%p;
   if(Hash.query(s)!=-1) return i*m-Hash.query(s);
  }
  return -1;
}
View Code

 

转载于:https://www.cnblogs.com/VividBinGo/p/11452707.html

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值