高次同余笔记(二):extended-baby-step-giant-step算法

原创 2015年11月20日 00:41:14

终于稍微有点空了。。
我们来看这个方程:
这里写图片描述
a,b,p为常数且在int内。
注意到这次p可以为合数。
先来说说p为质数或者合数有什么问题。
对于a与p互质,那么有a^phi(p)=1(mod p),对于p是素数phi(p)==p-1,所以x的取值只要在0->n-2之中取就可以了.然而如果p为合数,phi(p) < p-1,这个范围不明确,就不好分块了。而且解是否存在,有几个,也很麻烦。
因此有extended-baby-step-giant-step算法。
考虑a与p不互质的情况:
对于上面的方程,我们可以考虑从x个a中拿出c个a与b和p消去公因子,直到a和p’互质为止。
一旦互质了,那么方程就是v*a^(x-c)=b’ (mod p’),v是拿出c个a消去公因子后剩下的东西,b’,p’是消去公因子的b,p。
这个时候还要求v的逆元,方程变为a^(x-c)=b’*v^(-1) (mod p’)。
此时就可以用baby-step-giant-step做了,答案为BSGS的答案+c。
注意:有可能c会大于x,所以必须约去一次就特判一次方程两边(就是v和b’)是不是相等了。如果两边相等那么直接返回c。
附HDU2815EXBSGS裸题代码(hash表乱写的所以很慢)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
ll a,b,p,ans,hsh[70000][2];
bool ishsh[70000];
void insert(ll x,ll t)
{
    ll p=x*12580%70000;
    while(ishsh[p])p=(p+1)%70000;
    ishsh[p]=1;
    hsh[p][0]=x;
    hsh[p][1]=t;
}
int query(ll x)
{
    ll p=x*12580%70000;
    while(hsh[p][0]!=x&&ishsh[p])
        p=(p+1)%70000;
    if(!ishsh[p])return -1;
    return hsh[p][1];
}
ll gcd(ll a, ll b)
{
    return b?gcd(b,a%b):a; 
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(!b){x=1;d=a;y=0;}
    else
    {
        exgcd(b,a%b,d,y,x);
        y-=a/b*x;
    }
}
ll inv(ll a,ll p)
{
    ll x,y,d;
    exgcd(a,p,d,x,y);
    return (x+p)%p;
}
ll BSGS(ll a,ll b,ll p)
{
    ll m=ceil(sqrt(p)),d=1,val=1,gcd,x,y,t;
    for(int i=0;i<m;++i)
    {
        insert(val,i);
        val=val*a%p;
    }
    for(int i=0;i<m;++i)
    {
        exgcd(d,p,gcd,x,y);
        x=(b/gcd*x%p+p)%(p/gcd);
        t=query(x);
        if(t!=-1)return i*m+t;
        d=d*val%p;
    }
    return -1;
}
ll EXBSGS(ll a,ll b,ll p)
{
    ll t,c=0,v=1;
    while((t=gcd(a,p))!=1)
    {
        if(b%t)return -1;
        p/=t;//p一定要先除
        b/=t;
        v=v*a/t%p;//因为这里%p是约去后的p
        ++c;
        if(b==v)return c;//特判
    }
    b=b*inv(v,p)%p;
    ll ret=BSGS(a,b,p);
    return ret!=-1?ret+c:ret;
}
int main()
{
    while(~scanf("%I64d%I64d%I64d",&a,&p,&b))
    {
        memset(hsh,0,sizeof hsh);
        memset(ishsh,0,sizeof ishsh);
        if(b>=p)puts("Orz,I can’t find D!");//引号是全角的- -
        else if(b==0)puts("0");
        else if((ans=EXBSGS(a,b,p))==-1)puts("Orz,I can’t find D!");
        else printf("%I64d\n",ans);
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

机器学习之numpy和matplotlib学习(二)

第二天更新 今天我们来学习怎么使用matplotlib和numpy来做一个简单的图像。 先从代码入手,代码介绍如下: 我们要做一个y=x*x的图像,也就是初中经常学的一元二次函数的图像。 x是...
  • qq_33094993
  • qq_33094993
  • 2017年06月28日 21:12
  • 124

高次同余方程式的解数及解法

分类: 数论2013-07-26 18:41 561人阅读 评论(0) 收藏 举报 定理一: 若是k个两两互质的正整数,,则同余式                   ...
  • pi9nc
  • pi9nc
  • 2014年05月25日 22:20
  • 728

c++对一元n次方程近似解求法(不涉及大数)

二分法求解
  • maoshaomiao
  • maoshaomiao
  • 2016年03月14日 18:41
  • 980

iOS 高德地图 单次定位

定位知识: //地图 @property (nonatomic, strong) MAMapView *mapView; //位置管理器 @property (nonatomic, strong) A...
  • Xiejunyi12
  • Xiejunyi12
  • 2016年10月26日 16:35
  • 1022

[数学]齐次线性方程组的解、SVD、最小二乘法

AX=0 这是一个齐次线性方程组(一般的非齐次线性方程组AX=b其实也都可以化为齐次方程组的形式,所以比较普遍) 这个方程根据A来分,有几种情况: 1.r(A)=未知数个数(约束刚刚好) 1.1.A...
  • DSbatigol
  • DSbatigol
  • 2013年07月30日 17:02
  • 9951

最小二乘算法之我见(一)

从五个方面来讲解最小二乘算法,即基本直线拟合、"正规方程(Normal Equation)" 解法、扩展1——平面拟合、扩展2——般线性拟合(二次曲线等)、特殊情况,给你不一样的视角来看最小二乘法。...
  • popo_0314
  • popo_0314
  • 2016年04月29日 13:30
  • 2534

2016蓝桥杯算法训练——2的次幂表示

算法训练    2的次幂表示 问题描述   任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。   将这种2进制表示写成2的次幂的和的形式,令次幂高的排在...
  • qq_21385857
  • qq_21385857
  • 2016年03月13日 10:37
  • 775

高次同余笔记(一):baby-step-giant-step算法

我们来看这个方程: a,b,p为常数且在int内。、p是质数。 这个怎么搞? 首先x的取值肯定在0到p-1之间。 暴搜?肯定超时啊。 优化暴搜?用meet-in-the-middle? ...
  • Quack_quack
  • Quack_quack
  • 2015年11月17日 00:35
  • 947

《TCP/IP详解卷2:实现》笔记--TCP的输入

当收到的数据报的协议字段指明这是一个TCP报文段时,ipintr(通过协议协议转换表中的pr_input函数)会调用tcp_input 进行处理,tcp_inut在软件中断一级执行。 函数非常长,我们...
  • TODD911
  • TODD911
  • 2015年01月06日 22:45
  • 1694

齐次线性方程组的解、SVD、最小二乘法

转载出处:http://blog.csdn.net/ccwwff/article/details/45912671 AX=0 这是一个齐次线性方程组(一般的非齐次线性方程组AX=b...
  • zhangchunbo135246
  • zhangchunbo135246
  • 2015年06月24日 15:23
  • 765
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高次同余笔记(二):extended-baby-step-giant-step算法
举报原因:
原因补充:

(最多只允许输入30个字)