BSGS算法!

求解关于x的方程

a^x=z(mod p),其中gcd(a,p)=1.

做法的话并不难,但是要搞懂细节还蛮多的。

bsgs算法是这样的:x可以写成i*m-j的形式(这里m取值随意,但是取√p上取整时跑的最快)

  a^(im-j)≡z(mod p)

  推得  a^im≡z*(a^j)

那么我们枚举j的值从0--(m-1),将算出的z*(a^j)加入map里面

再枚举i从1-m,将每次算出的a^im的结果去map中匹配

若匹配到,x=i*m-j。

细节

1.i的范围从1到m

证明:

a ^ x Ξ b (mod p)

a ^ (p-1) Ξ 1 (mod p)

若x大于等于p-1

则a^xΞa^(p-1) * a^(x-p+1)Ξa^(x-p+1)

故x小于p-1

又m=√p

故i从1到m

得证

2.为什么bsgs在跳步过程中没有漏解

原因:在枚举i的过程中,看似是跳过了好多情况,但是其实在计算了每一个i之后,都会去map里面找每一个j去对应,相当于是将每一个i所对应的余数(剩余系)都枚举了一遍,即枚举了一遍完整的x的范围(因为x=i*m-j)。

模板题https://www.luogu.org/problemnew/show/P2485

洛谷p2485  计算器

bsgs裸题

直接粘代码

CODE!

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll t,k,y,z,p;
map<ll,ll>a;
ll fpow(ll a,ll b,ll p)
{
    ll ret=1;
    while(b)
    {
        if(b&1) ret=(ret*a)%p;
        b>>=1;
        a=(a*a)%p;
    }
    return ret;
}
void exgcd(ll a,ll b,ll &gcd,ll &xx,ll &yy)
{
    if(!b)
    {
        xx=1,yy=0;
        gcd=a;
        return;
    }
    exgcd(b,a%b,gcd,xx,yy);
    ll tr=xx;
    xx=yy;
    yy=tr-a/b*yy;
}
int main()
{
    cin>>t>>k;
    if(k==1)
    {
        while(t--)
        {
            scanf("%lld%lld%lld",&y,&z,&p);
            printf("%lld\n",fpow(y,z,p));
        }
    }
    else if(k==2)
        {
            while(t--)
            {
                scanf("%lld%lld%lld",&y,&z,&p);
                ll gcd,xx,yy;
                exgcd(y,p,gcd,xx,yy);
                if(z%gcd!=0) printf("Orz, I cannot find x!\n");
                else
                {
                    xx*=z/gcd;
                    xx%=(p/gcd);
                    printf("%lld\n",(xx+(p/gcd))%(p/gcd));
                }
            }

        }
        else
        {
            while(t--)
            {
                scanf("%lld%lld%lld",&y,&z,&p);
                ll m=ceil(sqrt(p));
                if(y%p==0&&z) {printf("Orz, I cannot find x!\n");continue;};
                a.clear();
                ll now=z%p,f=fpow(y,m,p);
                a[now]=0;
                for(ll i=1;i<=m;i++)
                {
                    now=(now*y)%p;
                    a[now]=i;
                }
                now=1;
                ll flag=0;
                for(ll i=1;i<=m;i++)
                {
                    now=(now*f)%p;
                    if(a[now])
                    {
                        ll ans=(i*m-a[now])%p;
                        printf("%lld\n",(ans+p)%p);
                        flag=1;
                        break;
                    }
                }
                if(!flag) printf("Orz, I cannot find x!\n");
            }
        }
    return 0;
}

ps.不开long long见祖宗可还行

原文地址:https://www.cnblogs.com/oierglh/p/11234686.html

时间: 2024-11-08 04:09:19

BSGS算法!的相关文章

bzoj2242: [SDOI2011]计算器 &amp;&amp; BSGS 算法

BSGS算法 给定y.z.p,计算满足yx mod p=z的最小非负整数x.p为质数(没法写数学公式,以下内容用心去感受吧) 设 x = i*m + j. 则 y^(j)≡z?y^(-i*m)) (mod p) 则 y^(j)≡z?ine(y^(i*m)) (mod p)(逆元) 由费马小定理y^(p-1)≡1 (mod p) 得 ine(y^m) = y^(p-m-1)  ine(y^(i*m)≡ine(y^((i?1)m))?y^(p-m-1)  1.首先枚举同余符号左面,用一个hash保存

BSGS算法学习小记(大步小步算法)

简介 先看一个式子xy≡z(modp),z是质数 现在只知道x和z,要求y. 大步小步算法(BSGS,Baby Steps Giant Steps)就是解决这个问题. 算法流程 暴搜的枚举范围 根据费马小定理:xz?1≡1. 如果y已经枚举到了z-1了,继续枚举的话就会产生循环. 所以,在暴搜中y的枚举范围就是0--z-1. 如何优化暴搜 我们想一想可不可以用分块来解决枚举的y. 把y分成p?1????√分别枚举行不行? 设m=p?1????√,y=a?m+b,这样枚举a和b就相当于分块枚举了.

BSGS算法+逆元 POJ 2417 Discrete Logging

POJ 2417 Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4860   Accepted: 2211 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarith

BSGS算法_Baby steps giant steps算法(无扩展)最强详解,你从未见过的详细

Baby Steps-Varsity Giant Step-Astronauts(May'n?椎名慶治) 阅读时可以听听这两首歌,加深对这个算法的理解.(Baby steps少女时代翻唱过,这个原唱反而不是很有名……Giant Step就比较碉,是一个假面骑士片的插曲,由超碉的May'n和一个人建立的临时组合唱的,怕不怕) 这个主要是用来解决这个题: A^x=B(mod C)(C是质数),都是整数,已知A.B.C求x. 我在网上看了好多介绍,觉得他们写得都不够碉,我看不懂…于是我也来写一发. 先

BSGS算法及拓展

https://www.zybuluo.com/ysner/note/1299836 定义 一种用来求解高次同余方程的算法. 一般问题形式:求使得\(y^x\equiv z(mod\ p)\)的最小非负\(x\). \(BSGS\)算法 要求\(p\)是质数. 由费马小定理可知,\(y^{p-1}\equiv1(mod\ p)\),所以暴力枚举只要枚举到\(p?1\)即可. 但是由于\(p\)一般都很大,所以一般都跑不动... 优化算法\(ing...\) 现在令\(x=mi?j\)(其中\(m

BSGS算法初探

前言 $BSGS$算法,全称$Baby Step Giant Step$,即大小步算法.某些奆佬也称其为拔(Ba)山(Shan)盖(Gai)世(Shi)算法. 它的主要作用是求解形式如$x^t\equiv y(mod MOD)$的式子中$t$的值. 而且,它是一个简单易懂的算法(毕竟连我这样的数学渣渣都能理解). 一个简单的性质 首先,我们需要知道一个简单的性质. 由费马小定理可得,$x^{MOD-1}\equiv1(mod MOD)$. $Link$ 费马小定理详见博客筛素数方法(二)-- 费

BSGS算法(大小步算法)

$BSGS$ 算法 $Baby\ Steps\ Giant\ Steps$. 致力于解决给定两个互质的数 $a,\ p$ 求一个最小的非负整数 $x$ 使得 $a^x\equiv b(mod\ p)$ 其中 $b$ 为任意正整数,$2≤a<p$,$2≤b<p$ 该算法使用的原理与欧拉定理有关,其中$a,\ p$互质 $a^{\phi (p)}\equiv 1(mod\ p)$ 又因为 $a^0\equiv 1(mod\ p)$ 所以$0到\phi p$是一个循环节,也就是说该算法最多查找$\p

高次不定方程BSGS算法

学习数学真是一件赛艇的事. BSGS名字听起来非常有意思,力拔山兮气盖世,北上广深,小步大步...算法其实更有意思,它是用来求解一个方程的 \(A^x≡B mod P\) 是不是特别眼熟,有几个式子长的特别像,先观察一下: 一:快速幂: 求\(A^B mod P\)的值 二:乘法逆元 \(A*x ≡ 1 (mod P)\) 或者 \(A*x ≡ B (mod P)\) 三:欧拉定理 \(A^{φ(P)}≡ 1 (mod P)\) (A,P互质) 四:费马小定理 \(A^{P-1} ≡ 1 (mo

BSGS算法

问题: 给出a,b,p,求x使得a^x对p取模是b. 1.令r是一个小于根号p范围的数. 2.循环a^0,a^1,a^2......a^r-1,如果有满足条件的,算法结束. 3.否则我们设x=cr-d(为什么是-d呢,主要是为了方便后面把a^d放到右边),然后我们得到了:a^cr对p取模是b*a^d 4.现在我们观察这个式子,其中b*a^d是不变的(0<=d<r),所以我们把所有的b*a^d存入Hash,枚举c小于根号p,再看(a^r)^c是否在Hash中出现 复杂度O(p^(1/2))