[CQOI2018]破解D-H协议
嘟嘟嘟
这不就是个bsgs板儿嘛。
顺便就复习了一下bsgs和哈希表。
头一次觉得我的博客这么好用,一下就懂了:数论学习笔记之高次不定方程
这里再补充几点:
1.关于这一段代码:
int S = sqrt(c), p = 1;
for(int i = 0; i < S; ++i)
{
if(p == b) return i + cnt;
insert(1LL * p * b % c, i);
p = 1LL * p * a % c;
}
for(int i = S, q = p; i - S + 1 < c; i += S)
{
int t = query(q);
if(~t) return i - t + cnt;
q = 1LL * q * p % c;
}
这一段是bsgs里最核心的部分。
首先是为什么\(q\)每一次乘以\(p\):第一层循环后,\(p\)就成为了\(a ^ m\),这样就相当于\(a ^ {i * m}\)。
然后是第二层循环的终止条件为什么是这个:大家都知道,这一段代码是枚举\(a ^ {tm}\)的,只不过用\(i\)代替了\(tm\),所以我们考虑\(i\)的最大值:\(tm - y < c \Rightarrow i - (m - 1) < c \Rightarrow i - m + 1 < c\) 。这就出来了。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int base = 99979;
const int maxe = 1e6 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int g, P, n;
In ll quickpow(ll a, ll b, ll mod)
{
ll ret = 1;
for(; b; b >>= 1, a = a * a % mod)
if(b & 1) ret = ret * a % mod;
return ret;
}
In ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
In void exgcd(ll a, ll b, ll& x, ll& y)
{
if(!b) x = 1, y = 0;
else exgcd(b, a % b, y, x), y -= a / b * x;
}
In ll inv(ll a, ll mod)
{
ll x, y;
exgcd(a, mod, x, y);
return x;
}
struct Hash
{
int nxt, to, w;
}e[maxe];
int head[base], ecnt = 0;
int st[base], top = 0;
In void init()
{
ecnt = 0;
while(top) head[st[top--]] = 0;
}
In void insert(int x, int y)
{
int h = x % base;
if(!head[h]) st[++top] = h;
e[++ecnt] = (Hash){head[h], x, y};
head[h] = ecnt;
}
In int query(int x)
{
int h = x % base;
for(int i = head[h]; i; i = e[i].nxt)
if(e[i].to == x) return e[i].w;
return -1;
}
In int bsgs(int a, int b, int c)
{
int Gcd, d = 1, cnt = 0;
while((Gcd = gcd(a, c)) ^ 1)
{
if(b % Gcd) return -1;
++cnt; b /= Gcd, c /= Gcd;
d = 1LL * d * (a / Gcd) % c;
}
b = 1LL * b * inv(d, c) % c;
init();
int S = sqrt(c), p = 1;
for(int i = 0; i < S; ++i)
{
if(p == b) return i + cnt;
insert(1LL * p * b % c, i);
p = 1LL * p * a % c;
}
for(int i = S, q = p; i - S + 1 < c; i += S)
{
int t = query(q);
if(~t) return i - t + cnt;
q = 1LL * q * p % c;
}
return -1;
}
int main()
{
g = read(), P = read(), n = read();
for(int i = 1; i <= n; ++i)
{
int A = read(), B = read();
write(quickpow(g, 1LL * bsgs(g, A, P) * bsgs(g, B, P) , P)), enter;
}
return 0;
}
[CQOI2018]破解D-H协议的更多相关文章
- BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS
BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS Description Diffie-Hellman密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码 ...
- BZOJ5296 CQOI2018 破解D-H协议 【BSGS】
BZOJ5296 CQOI2018Day1T1 破解D-H协议 Description Diffie-Hellman密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码) ...
- BZOJ5296 [CQOI2018] 破解D-H协议 【数学】【BSGS】
题目分析: 裸题. 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; ; #define mp ...
- 2018.12.18 bzoj5296: [Cqoi2018]破解D-H协议(bsgs)
传送门 bsgsbsgsbsgs基础题. 考虑到给的是原根,因此没无解的情况. 于是只需要每次把a,ba,ba,b解出来. 然后可以通过预处理节省一部分时间. 代码: #include<bits ...
- LG4454 【[CQOI2018]破解D-H协议】
先谈一下BSGS算法(传送门) 但是上面这位的程序实现比较繁琐,看下面这位的. clover_hxy这样说 bsgs算法,又称大小步算法(某大神称拔山盖世算法). 主要用来解决 A^x=B(mod C ...
- BZOJ 5296: [Cqoi2018]破解D-H协议(BSGS)
传送门 解题思路 \(BSGS\)裸题??要求的是\(g^a =A (mod\) \(p)\),设\(m\)为\(\sqrt p\),那么可以设\(a=i*m-j\),式子变成 \[ g^{i*m-j ...
- P4454 [CQOI2018]破解D-H协议
链接 这题并不难只是需要把题读懂 - By ShadderLeave 一句话题意 给定两个数 \(p\)和\(g\),有\(t\)组询问,每组询问给出\(A\)和\(B\) 其中 A = \(g^a ...
- 破解使用SMB协议的Windows用户密码:acccheck
一.工作原理 Acccheck是一款针对微软的SMB协议的探测工具(字典破解用户名和密码),本身不具有漏洞利用的能力. SMB协议:SMB(Server Message Block)通信协议主要是作为 ...
- Linux 利用hosts.deny 防止暴力破解ssh(转)
一.ssh暴力破解 利用专业的破解程序,配合密码字典.登陆用户名,尝试登陆服务器,来进行破解密码,此方法,虽慢,但却很有效果. 二.暴力破解演示 2.1.基础环境:2台linux主机(centos 7 ...
随机推荐
- 快速掌握JavaScript面试基础知识(二)
译者按: 总结了大量JavaScript基本知识点,很有用! 原文: The Definitive JavaScript Handbook for your next developer interv ...
- for、for / in循环
1.for循环 循环代码块一定的次数 <!DOCTYPE html> <html lang="en" dir="ltr"> <he ...
- POJ 1704 Georgia and Bob(阶梯Nim博弈)
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11357 Accepted: 3749 Description Geor ...
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...
- django模型基础(三)
本文转载自https://blog.csdn.net/xiaogeldx/article/details/88084034 表关系 一对一(OneToOne) 通过本表的主键外键关联另一张表的主键 创 ...
- 性能优化4--Bitmap内存优化
1.Bitmap在Android虚拟机中的内存分配 在Android3.0之前,Bitmap的内存分配分为两部分,一部分是分配在Dalvik的VM堆中.而像素数据的内存是分配在Native堆中,而到了 ...
- Android Studio多渠道打包(二)
虽然多渠道打包的方式有很多种,那么今天我要说的通过工具的形式进行多渠道打包 首先,打开Android studio,找到顶部Build,点开 选择红色部分,里面的编辑框可以帮助我们更快的熟悉Gradl ...
- (网页)sweetalert api 中文开发文档和手册,项目放弃alert
弹框json的特别好使. sweetalert 示例 基本信息弹窗swal("这是一条信息!") 标题与文本的信息弹窗swal("这是一条信息!", " ...
- 通过UNIX域套接字传递描述符的应用
传送文件描述符是高并发网络服务编程的一种常见实现方式.Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现.本文详细说明一下传送文件描述符的应用. 1. TCP服务器程 ...
- Kotlin的参考资料
参考资料和站点 http://kotlinlang.org/ 官方网站 https://github.com/JetBrains/kotlin/releases/tag/v1.0.6 下载compil ...