「题解」 [CQOI2018]破解D-H协议

2023-10-24 00:59
文章标签 协议 破解 题解 cqoi2018

本文主要是介绍「题解」 [CQOI2018]破解D-H协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

人生中第一道紫题,写一篇题解纪念一下。

BSGS

BSGS(拔山盖世,北上广深 )是什么呢?

它是一种能够在 O ( n ) O(\sqrt n\space) O(n  )的时间复杂度内求解类似于 a x ≡ b ( m o d p ) a^x \equiv b \pmod{p} axb(modp)的算法。

首先,我们设 x = i p − j x=i\sqrt p-j x=ip j,其中 i , j ∈ [ 0 , p ] i,j\in [0,\sqrt p\space] i,j[0,p  ]

那么这个式子就变成了 a i p − j ≡ b ( m o d p ) a^{i\sqrt p-j} \equiv b\pmod p aip jb(modp)

两边同时乘上 a j a^j aj,很显然,等式变成了

a i p ≡ b a j ( m o d p ) a^{i\sqrt p} \equiv ba^j\pmod p aip baj(modp)

到了这一步,我们就可以先枚举 j j j,每次把 b a j m o d p ba^j\bmod p bajmodp存入哈希表。

然后再枚举 i i i,在哈希表中查找 a i p a^{i\sqrt p} aip ,如果找到了,就说明这个等式成立, x x x就应该是 i p − j i\sqrt p-j ip j,如果枚举完了也没找着,就说说明这个等式不成立。

在这个过程中,我们仅仅枚举了两次,时间复杂度只有区区的 O ( n ) O(\sqrt n\space) O(n  )

题目大意

看起来这个题目很复杂,但其实就是一个BSGS的模板。

简化一下题意,题目告诉你 g a m o d p g^a\bmod p gamodp g b m o d p g^b\bmod p gbmodp,让你求 g a b m o d p g^{ab}\bmod p gabmodp

观察一下,我们发现
g a b m o d p g^{ab}\bmod p gabmodp = ( g a ) b m o d p =(g^a)^b\bmod p =(ga)bmodp = ( g a m o d p ) b m o d p =(g^a\bmod p)^b\bmod p =(gamodp)bmodp = A b m o d p = A^b\bmod p =Abmodp

也就是说,只要我们把 b b b求出来,那就万事大吉了。

那么如何求 b b b呢?

观察发现:

B = g b m o d P B=g^b\bmod P B=gbmodP B ≡ g b ( m o d P ) B \equiv g^b\pmod P Bgb(modP) g b ≡ B ( m o d P ) g^b \equiv B\pmod P gbB(modP)

这不就是BSGS的模板吗?

我们可以用BSGS求出 b b b,然后把用 b b b求出 A b m o d p A^b\bmod p Abmodp

有了这个思路,我们就可以开始写代码了!

代码:

#include <bits/stdc++.h>
using namespace std;
int g,n,p;//在最开始就定义三个全局变量
int qpow(int a,int b){//快速幂模板int res=1;while(b){if(b&1) res=(a*res)%p;a=(a*a)%p;b>>=1;}return res;
}
int BSGS(int b){map<int,int>m;//哈希表可以用map代替int t=ceil(sqrt(p));//记得要向上取整for(int i=1;i<=t;i++) m[b*qpow(g,i)%p]=i;//枚举j,存入哈希表中for(int i=1;i<=t;i++){int k=qpow(g,i*t)%p;if(m[k]) return i*t-m[k];//如果在哈希表中找到了这个值,就说明找到了b}return -1;//如果没有找到,就说明无解
}int main(){cin>>g>>p>>n;for(int i=1;i<=n;i++){int A,B;cin>>A>>B;int b=BSGS(B);//用BSGS求出bcout<<qpow(A,b)%p<<endl;//用快速幂求出K}return 0;
}

如果把这份代码提交到洛谷上,那么就会出现

请添加图片描述
万紫千红的场面。

我们可以尝试着开longlong。

#define int long long

提交后发现

请添加图片描述

WA没了,就变成了tle。

我们可以使用printfscanf

请添加图片描述

优化了却没有完全优化。

抱着侥幸的心理,我开了O2,结果发现。
请添加图片描述

这玄学的数据!

完整代码(记得开O2):

#include <bits/stdc++.h>
#define int long long
using namespace std;
int g,n,p;//在最开始就定义三个全局变量
int qpow(int a,int b){//快速幂模板int res=1;while(b){if(b&1) res=(a*res)%p;a=(a*a)%p;b>>=1;}return res;
}
int BSGS(int b){map<int,int>m;//哈希表可以用map代替int t=ceil(sqrt(p));//记得要向上取整for(int i=1;i<=t;i++) m[b*qpow(g,i)%p]=i;//枚举j,存入哈希表中for(int i=1;i<=t;i++){int k=qpow(g,i*t)%p;if(m[k]) return i*t-m[k];//如果在哈希表中找到了这个值,就说明找到了b}return -1;//如果没有找到,就说明无解
}signed main(){scanf("%lld%lld%lld",&g,&p,&n);for(int i=1;i<=n;i++){int A,B;scanf("%lld%lld",&A,&B);int b=BSGS(B);//用BSGS求出bprintf("%lld\n",qpow(A,b)%p);//用快速幂求出K}return 0;
}

这篇关于「题解」 [CQOI2018]破解D-H协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/271637

相关文章

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

Modbus-RTU协议

一、协议概述 Modbus-RTU(Remote Terminal Unit)是一种基于主从架构的通信协议,采用二进制数据表示,消息中的每个8位字节含有两个4位十六进制字符。它主要通过RS-485、RS-232、RS-422等物理接口实现数据的传输,传输距离远、抗干扰能力强、通信效率高。 二、报文结构 一个标准的Modbus-RTU报文通常包含以下部分: 地址域:单个字节,表示从站设备

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析