主頁 >  其他 > (ex)BSGS/(擴展)大步小步演算法 學習筆記

(ex)BSGS/(擴展)大步小步演算法 學習筆記

2023-06-05 08:12:44 其他

(ex)BSGS/(擴展)大步小步演算法 學習筆記

在即將暫時退役之際殺掉了P4195的毒瘤模板題,于是來寫篇學習筆記,

謹此為我初中三年擺爛的OI生涯畫上一個句號,(距離中考還有20天!)

BSGS

link

\(a^x\equiv b\pmod p\)非負整數解,其中\(a, p\)互質,

演算法思路

我們不妨令\(t=\lceil{\sqrt{p}\rceil}\)\(j\lt t\)\(i\leq t\)

原式轉化為\(a^{it-j} \equiv b \pmod p\)

\(\left(a^t\right)^i\equiv b\cdot a^j \pmod p\)

于是我們可以這么在\(\Theta\left(\sqrt{n}\right)\)(不考慮hash表)內求出解:

  • 列舉\(j \in [0, t)\),求出所有的\(b\cdot a^j \mod p\),用hash表記錄下來

  • 列舉\(i \in [0, t]\),求出所有的\(\left(a^t\right)^i \mod p\),在hash表中查找是否有對應的\(j\)

需要注意的是,當\(a^t \mod p=0\)時,若\(b=0\),則解為\(x=1\)
否則無解,

正確性討論

由Euler定理,我們有\(a^{\varphi\left(p\right)}\equiv 1\pmod p\),其中\(\varphi\left(x\right)\)為Euler函式,

也就是說,\(\mod p\)意義下,\(a^x\mod p\)\(x=n\cdot\varphi\left(p\right)\)\(n\)遍歷非負整數)后回圈,

我們知道對于任意整數\(p \gt 1\)\(p>\varphi\left(p\right)\),而我們取的\(it-j\)可以遍歷\([0, x]\),因此能夠取到\(a^p \mod p\)的一切情況,故一定不會漏解,

代碼實作

#include <bits/stdc++.h>

using namespace std;

#define int long long

int qpow(int a, int n, int p) {
    a%=p;
    int res=1;
    while (n) {
        if (n&1) res=res*a%p;
        a=a*a%p;
        n>>=1;
    }
    return res;
}

signed bsgs(int a, int b, int p) {
    b%=p;
    int t=sqrt(p)+1;
    unordered_map<int, int> hash; hash.clear();
    for (int j=0; j<t; ++j) {
        int power=b*qpow(a,j,p)%p;
        hash[power]=j;
    }
    a=qpow(a,t,p);
    if (a==0) return b==0?1:-1;
    for (int i=0; i<=t; ++i) {
        int val=qpow(a,i,p);
        int j=hash.find(val)==hash.end()?-1:hash[val];
        if (j>=0 && i*t-j>=0) return i*t-j;
    }
    return -1;
}

signed main() {
    int a, b, p;
    cin>>p>>a>>b;
    int res=bsgs(a,b,p);
    if (res==-1) puts("no solution");
    else cout<<res<<endl;
    return 0;
}

這份代碼是可以通過P3846的,我們可以考慮對它進行優化,

我們發現列舉\(a^j\)\(\left(a^t\right)^i\)的時候,\(i, j\)是遞增的,于是我們可以直接用一個變數來維護\(a^j\)\(\left(a^t\right)^i\)

另外,用unordered_map來實作hash表似憾訓快一些,

inline int bsgs(int a, int b, int p) {
    int t=(int)(sqrt(p))+1;
    unordered_map<int,int> h; h.clear();
    int powa=1;
    for (reg int j=0; j<t; ++j) {
        int val=powa*b%p;
        h[val]=j;
        powa=powa*a%p;
    }
    a=qpow(a,t,p);
    powa=1;
    for (reg int i=0; i<=t; ++i) {
        int val=powa%p;
        int j=h.find(val)==h.end()?-1:h[val];
        if (j>=0 && i*t-j>=0) return i*t-j;
        powa=powa*a%p;
    }
    return -1;
}

為exBSGS進行修改

我們現在來考慮\(ka^x\equiv b\pmod p\)\(a, p\)互質,\(k\)為正整數)的式子,我們可以同樣地將它們變形為

\[k\cdot \left(a^t\right)^i\equiv b\cdot a^j \pmod p \]

于是稍微修改一下上述代碼就可以了,

inline int bsgs(int a, int b, int k, int p) {
    int t=(int)(sqrt(p))+1;
    unordered_map<int,int> h; h.clear();
    int powa=1;
    for (reg int j=0; j<t; ++j) {
        int val=powa*b%p;
        h[val]=j;
        powa=powa*a%p;
    }
    a=qpow(a,t,p);
    powa=1;
    for (reg int i=0; i<=t; ++i) {
        int val=k*powa%p;
        int j=h.find(val)==h.end()?-1:h[val];
        if (j>=0 && i*t-j>=0) return i*t-j;
        powa=powa*a%p;
    }
    return -1;
}

exBSGS

link

\(a^x\equiv b\pmod p\)非負整數解,其中\(a, p\)未必互質

演算法思路

考慮利用同余式的約化性質,轉換成樸素的BSGS來求解,

我們有如下同余式的約化性質:
\(a\equiv b\pmod p\)\(d\mid a,d \mid b\),則

\(\frac{a}{d}\equiv\frac{b}{d}\pmod {\frac{p}{\gcd(d,p)}}\)

我們回到\(a^x\equiv b\pmod p\),令\(d_1=\gcd(a,p)\)
\(d_1 \mid b\),我們可以變形為
\(\frac{a}{d_1}\cdot a^{x-1}\equiv \frac{b}{d_1} \pmod {\frac{p}{d_1}}\)
(若\(d_1 \nmid b\),立刻得出無解)
\(a,\frac{p}{d_1}\)仍不互質,我們可以繼續令\(d_2=\gcd(a,\frac{p}{d_1})\)\(\cdots\),直到\(a,\frac{p}{d_1d_2\cdots d_k}\)互質為止,

我們設一共進行了\(k\)次約化,\(D=d_1d_2\cdots d_k\)(此時\(a\)\(\frac{p}{D}\)互質),原式可變形為

\(\frac{a^k}{D}\cdot a^{x-k} \equiv \frac{b}{D} \pmod {\frac{p}{D}}\)

我們令\(k=\frac{a^k}{D}, X=x-k, B=\frac{b}{D}, P=\frac{p}{D}\),即

\(ka^X\equiv B \pmod P\)

于是可以利用修改后的BSGS演算法來求解,

注意求解之后得到\(X=x-k\),故\(x=X+k\)

Trick

\(\frac{a^k}{D}=\frac{a}{d_1}\frac{a}{d_2}\cdots\frac{a}{d_k}\),于是可以在每一個回圈內單獨計算,

cout<<'\n'似憾訓比用cout<<endl快一些,

可以預先將b%=p, a%=p,若取模過后\(b==1\)或者\(p==1\),那么顯然\(x=0\)為解,

我們記\(D_k=\frac{a}{d1}\frac{a}{d2}\cdots \frac{a}{d_k}\),當\(\frac{a^k}{D^k}==\frac{b}{D_k}\)時,有

\[\frac{a^k}{D_k}\cdot a^{x-k}\equiv \frac{b}{D_k}\pmod {\frac{p}{D_k}} \]

\[a^{x-k}\equiv 1\pmod {\frac{p}{D_k}} \]

于是\(x=k\)為解,其中\(k\)是正在進行的第\(k\)次約化,

代碼實作

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define reg register
inline int qpow(int a, int n, int p) {
    a%=p; int res=1;
    while (n) {
        if (n&1) res=res*a%p;
        a=a*a%p; n>>=1;
    }
    return res;
}
inline int bsgs(int a, int b, int k, int p) {
    int t=(int)(sqrt(p))+1;
    unordered_map<int,int> h; h.clear();
    int powa=1;
    for (reg int j=0; j<t; ++j) {
        int val=powa*b%p;
        h[val]=j;
        powa=powa*a%p;
    }
    a=qpow(a,t,p);
    powa=1;
    for (reg int i=0; i<=t; ++i) {
        int val=k*powa%p;
        int j=h.find(val)==h.end()?-1:h[val];
        if (j>=0 && i*t-j>=0) return i*t-j;
        powa=powa*a%p;
    }
    return -1;
}
inline int exbsgs(int a, int b, int p) {
    a%=p, b%=p;
    if (b==1 || p==1) return 0;
    int A=a, NA=1, B=b, P=p, k=0, D=1;
    while (__gcd(a,P)>1) {
        int d=__gcd(a,P);
        if (B%d) return -1;
        k++; A/=d, B/=d, P/=d, NA=NA*(a/d)%P, D=D*d%P;
        if (NA==B) return k; // NA就是上文提到的(a^k)/(D^k)
    }
    int res=bsgs(a,B,NA,P);
    if (res==-1) return res;
    if ((qpow(a,res+k,p)-b)%p) return -1;
    return res+k;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    int a, b, p;
    while (cin>>a>>p>>b && a) {
        int res=exbsgs(a,b,p);
        if (res==-1) cout<<"No Solution\n";
        else cout<<res<<'\n';
    }
    return 0;
}

Record,\(2.46\rm{s}\),可以通過本題(包括Hack資料),

后記

這道題算是比較毒瘤的,我是一共調了三天才過的(我太弱了)
還有\(20\)天就要中考了,而我還在這摸魚(悲)
就謹此紀念一下我的初中OI生涯罷,

順便在此祝福向宴醬中考順利!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/554289.html

標籤:其他

上一篇:自我的創建

下一篇:返回列表

標籤雲
其他(160342) Python(38201) JavaScript(25475) Java(18185) C(15236) 區塊鏈(8269) C#(7972) AI(7469) 爪哇(7425) MySQL(7231) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5346) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4582) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1981) 功能(1967) HtmlCss(1952) Web開發(1951) C++(1928) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • (ex)BSGS/(擴展)大步小步演算法 學習筆記

    # (ex)BSGS/(擴展)大步小步演算法 學習筆記 在即將暫時退役之際殺掉了[P4195](https://www.luogu.com.cn/problem/P4195)的毒瘤模板題,于是來寫篇學習筆記。 謹此為我初中三年擺爛的OI生涯畫上一個句號。(距離中考還有20天!) ## BSGS [li ......

    uj5u.com 2023-06-05 08:12:44 more
  • 自我的創建

    分享下今天看到的一些知識,也不算是知識吧.更多的是對自己的一種認識.我從自身的經歷來劃分的幾個階段,來展示自我的發展方式,這個只是針對在幼年時的狀態 之所以稱為完美的,是因為各種方向基本可以確定,很容易找到邊界,成長起來相對穩定 這種缺失,影響并不是很大,缺失一條邊界后,可以利用自我探索的方式進行補 ......

    uj5u.com 2023-06-05 08:07:26 more
  • 域用戶列舉和密碼噴灑攻擊橫向移動

    # 域用戶列舉和密碼噴灑攻擊橫向移動 [TOC] ## 一、域內用戶列舉攻擊原理 正常域用戶登錄主機,我們可以通過 "net user /domain"來列舉出域內的用戶。但是當我們用非域用戶進行登錄時,是不能使用 "net user /domain"這條命令的。或者當主機不在域內但是能與域控通信時 ......

    uj5u.com 2023-06-05 08:02:18 more
  • NSSCTF Round#13 web專項

    ### rank:3 ## flask?jwt? 簡單的注冊個賬號,在`/changePassword ` 下查看頁面源代碼發現密鑰`` ,很好,老套路了,flask-session-cookie-manager偽造,把`_user_id` 改成1,訪問`/getFlag` ,拿到flag ## e ......

    uj5u.com 2023-06-05 08:02:07 more
  • Web安全-滲透測驗-基礎知識01

    # 1.域名 >**定義:**域名(英語:Domain Name),又稱網域,是由一串用點分隔的名字組成的互聯網上某一臺計算機或計算機組的名稱,用于在資料傳輸時對計算機的定位標識. 因為ip地址不方便記憶.而且不能顯示地址組織的名稱和性質,所以用域名也可以定位到回應的up,可簡單理解為是ip地址的另 ......

    uj5u.com 2023-06-05 08:01:33 more
  • git checkout switch restore

    ## 前言 在 Git 術語中,“checkout”是在目標物體的不同版本之間切換的行為。該命令對三個不同的物體進行操作:檔案、提交和分支。除了“checkout”的定義之外,短語“檢出”通常用于表示執行命令的行為。在[撤消更改](https://www.atlassian.com/git/tuto ......

    uj5u.com 2023-06-05 08:00:46 more
  • 為teamcity的代碼語法檢查工具pyflakes增加支持python2和python3

    ## TeamCity和pyflakes TeamCity是一款由JetBrains公司開發的持續集成和部署工具,它提供了豐富的功能來幫助團隊協作進行軟體開發。其中包括代碼檢查、自動化構建、測驗運行、版本控制等多個方面。 在我們團隊中使用TeamCity進行配合pyflakes代碼檢查,我們需要升級 ......

    uj5u.com 2023-06-05 08:00:40 more
  • Tengine 入門實戰(2)--簡單使用

    本文主要介紹 Tengine 的主動式后端服務器健康檢查的擴展功能,其他的擴展功能可參考官網檔案:http://tengine.taobao.org/;文中所使用到的軟體版本:Centos 7.9.2009、Tengine 2.3.3。 1、相關指令 1.1、check Syntax: check ......

    uj5u.com 2023-06-05 08:00:33 more
  • ChatGPT最全問答,你想知道的都在這里!

    ChatGPT最全問答,你想知道的都在這里!本文為你詳細解答了ChatGPT是什么、有哪些應用場景、如何更好地向ChatGPT提問以及ChatGPT的進階技巧,讓你輕松成為ChatGPT專家! ......

    uj5u.com 2023-06-05 08:00:20 more
  • ChatGPT最全問答,你想知道的都在這里!

    ChatGPT最全問答,你想知道的都在這里!本文為你詳細解答了ChatGPT是什么、有哪些應用場景、如何更好地向ChatGPT提問以及ChatGPT的進階技巧,讓你輕松成為ChatGPT專家! ......

    uj5u.com 2023-06-05 07:59:43 more