BSGS(大小步)算法

BSGS算法主要用于求解形如ax≡b(mod p)的式子中x的值。

在这里我们不妨设

x=k1*n-k2

这时我们就可以将式子转化为

ak1*n≡b*ak2(mod p)

这里的n我们设为√p,所以我们利用分块的思想在块数范围内枚举k1即可。那在考虑完k1和n之后我们再考虑一下如何找到k2,我们建立一个哈希表,将k2取0~n时的式子左边的值模p然后将其映射到此时k2的取值。求最后答案时我们只需找到在k1最小时满足条件的最大的k2即可。

模板(poj2417

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
map<long long,long long>mp;
inline long long pw(long long a,long long p,long long mod){
    long long res=1;
    while(p){
        if(p&1)res=res*a%mod;
        a=a*a%mod;
        p>>=1;
    }
    return res;
}
int main(){
    long long a,b,p,m,n,i,j,k,pl;
    while(scanf("%lld%lld%lld",&p,&a,&b)!=EOF){
        n=ceil(sqrt(p));
        mp.clear();
        long long x=b%p;
        mp[x]=0;
        for(i=1;i<=n;i++){
            x=x*a%p;
            mp[x]=i;
        }
        long long y=pw(a,n,p),ok=0;
        x=1;
        for(i=1;i<=n;i++){
           x=x*y%p;
           if(mp[x]){
                ok=1;
                pl=i;
                break;
           }
        }
        if(ok){
            printf("%lld\n",((pl*n%p-mp[x])%p+p)%p);
        }else puts("no solution");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yzxverygood/p/9160401.html

时间: 2024-11-08 04:08:44

BSGS(大小步)算法的相关文章

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算法学习小记(大步小步算法)

简介 先看一个式子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就相当于分块枚举了.

【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线代算法我也不想多说,还是自行百度吧 需要注意的是矩阵没有交换律,所以在计算$B\cdot A^{-m}$的时候不要把顺序搞混 代码: 1 #include <cstring> 2 #include <cstdio> 3 #include <algorithm> 4 #inc

数据挖掘十大经典算法

一. C4.5  C4.5算法是机器学习算法中的一种分类决策树算法,其核心算法是ID3 算法.   C4.5算法继承了ID3算法的优点,并在以下几方面对ID3算法进行了改进: 1) 用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足: 2) 在树构造过程中进行剪枝: 3) 能够完成对连续属性的离散化处理: 4) 能够对不完整数据进行处理. C4.5算法有如下优点:产生的分类规则易于理解,准确率较高.其缺点是:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导

数据挖掘领域十大经典算法初探

译者:July   二零一一年一月十五日 ----------------------------------------- 参考文献:国际权威的学术组织ICDM,于06年12月年评选出的数据挖掘领域的十大经典算法:C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART.==============博主说明:1.原文献非最新文章,只是本人向来对算法比较敏感.感兴趣,便把原文细看了下,翻译过程中

九大排序算法总结

九大排序算法再总结 算法的由来:9世纪波斯数学家提出的:“al-Khowarizmi” 排序的定义: 输入:n个数:a1,a2,a3,...,an 输出:n个数的排列:a1',a2',a3',...,an',使得a1'<=a2'<=a3'<=...<=an'. In-place sort(不占用额外内存或占用常数的内存):插入排序.选择排序.冒泡排序.堆排序.快速排序. Out-place sort:归并排序.计数排序.基数排序.桶排序. 当需要对大量数据进行排序时,In-plac

九大排序算法再总结

本文是 http://blog.csdn.net/xiazdong/article/details/7304239 的补充,当年看了<大话数据结构>总结的,但是现在看了<算法导论>,发现以前对排序的理解还不深入,所以打算对各个排序的思想再整理一遍. 本文首先介绍了基于比较模型的排序算法,即最坏复杂度都在Ω(nlgn)的排序算法,接着介绍了一些线性时间排序算法,这些排序算法虽然都在线性时间,但是都是在对输入数组有一定的约束的前提下才行. 这篇文章参看了<算法导论>第2.3

js十大排序算法详解

十大经典算法导图  图片名词解释:n: 数据规模k:"桶"的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外内存 1.冒泡排序 1.1  原始人冒泡排序 function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]

轻松看懂机器学习十大常用算法

轻松看懂机器学习十大常用算法 通过本篇文章可以对ML的常用算法有个常识性的认识,没有代码,没有复杂的理论推导,就是图解一下,知道这些算法是什么,它们是怎么应用的,例子主要是分类问题. 每个算法都看了好几个视频,挑出讲的最清晰明了有趣的,便于科普. 以后有时间再对单个算法做深入地解析. 今天的算法如下: 决策树 随机森林算法 逻辑回归 SVM 朴素贝叶斯 K最近邻算法 K均值算法 Adaboost 算法 神经网络 马尔可夫 1. 决策树 根据一些 feature 进行分类,每个节点提一个问题,通过

Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数排序) 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序. 先来看看 8种排序之间的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2]