LibreOJ2045 - 「CQOI2016」密钥破解
Description
给出三个正整数\(e,N,c(\leq2^{62})\)。已知\(N\)能表示成\(p\cdot q\)的形式,其中\(p,q\)为质数。计算\(r=(p-1)(q-1),ed\equiv 1 \pmod r\),求\(c^d \bmod N\)。
Solution
其实主要就是一件事:分解大数\(N\)。这里要用到一个叫做Pollard's Rho的算法,可以在约\(O(n^{\frac{1}{4}})\)的时间复杂度上求出一个\(n\)的因数。具体原理是生日悖论,但我不知道为什么这个是悖论...伪代码如下:
nxt(x)
return (x*x+step) mod n
PR(n)
while true
step=rand()
a=b=rand()
while true
a=nxt(a),b=nxt(nxt(b))
if(a==b) break
g=gcd(abs(a-b),n)
if(g!=1) return g
由于\(nxt(x)\)是循环的,所以用以\(a\)的两倍速度前进的\(b\)进行判断,一旦\(a=b\)则说明出现环,尝试换一个参数\(step\)去随机。
Code
//「CQOI2016」密钥破解
#include <bits/stdc++.h>
typedef long long lint;
lint n;
int pr[10]={0,2,3,5,7,11,13,17};
lint multi(lint a,lint b){lint t=a*b-(lint)((long double)a*b/n+1e-8)*n;if(t<0)return t+n;return t;}
inline lint abs(lint x) {return x<0?-x:x;}
inline lint gcd(lint x,lint y) {return y?gcd(y,x%y):x;}
int step;
inline lint nxt(lint x) {return (multi(x,x)+step)%n;}
lint PR(lint n)
{
while(true)
{
step=rand();
lint a,b; a=b=rand();
while(true)
{
a=nxt(a),b=nxt(nxt(b));
if(a==b) break;
lint g=gcd(abs(a-b),n);
if(g!=1) return g;
}
}
}
inline void exgcd(lint a,lint &x,lint b,lint &y)
{
if(b==0) {x=1,y=0; return;}
lint x1,y1; exgcd(b,x1,a%b,y1);
x=y1,y=x1-a/b*y1;
}
lint inv(lint a,lint m)
{
lint x,y; exgcd(a,x,m,y);
while(x<0) x+=m;
return x;
}
lint pow(lint x,lint y)
{
lint r=1,t=x;
for(lint i=y;i;i>>=1,t=multi(t,t)) if(i&1) r=multi(r,t);
return r;
}
int main()
{
lint e,c;
scanf("%lld%lld%lld",&e,&n,&c);
lint p=0,q=0;
for(int i=1;i<=7;i++) {if(n%pr[i]==0) p=pr[i],q=n/p; break;}
if(!p) p=PR(n),q=n/p;
lint d=inv(e,(p-1)*(q-1));
printf("%lld %lld\n",d,pow(c,d));
return 0;
}
LibreOJ2045 - 「CQOI2016」密钥破解的更多相关文章
- loj2045 「CQOI2016」密钥破解
CQOI 板子大赛之 pollard rho #include <iostream> #include <cstdio> using namespace std; typede ...
- LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree
2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- loj #2044. 「CQOI2016」手机号码
#2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ2044 - 「CQOI2016」手机号码
Portal Description 给出两个十一位数\(L,R\),求\([L,R]\)内所有满足以下两个条件的数的个数. 出现至少\(3\)个相邻的相同数字: 不能同时出现\(4\)和\(8\). ...
- LibreOJ2043 - 「CQOI2016」K 远点对
Portal Description 给出平面上的\(n(n\leq10^5)\)个整点,求在欧几里得距离下第\(k\)远的点对之间的距离. Solution k-d树+堆. 用小根堆维护当前找到的第 ...
- LibreOJ2042 - 「CQOI2016」不同的最小割
Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...
- 「CQOI2016」不同的最小割
「CQOI2016」不同的最小割 传送门 建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了. 参考代码: #include <algorithm> ...
- 「CQOI2016」K 远点对
/* 考虑暴力 可以n ^ 2枚举点对 然后用一个容量为2k的小根堆来维护第k大 kd-tree呢就是来将这个暴力优化, 每次先找远的并且最远距离不如堆顶的话就不继续找下去 貌似挺难构造数据卡的 */ ...
- 【LOJ】#2047. 「CQOI2016」伪光滑数
题解 可持久化可并堆 用\(f[i,j]\)表示最大的质数标号为i,然后有j个质数乘起来 用\(g[i,j]\)表示\(\sum_{k = 1}^{i}f[k,j]\) 转移是 \(f[i,j] = ...
随机推荐
- 在ProgressBar控件中显示进度百分比
实现效果: 知识运用: ProgressBar控件的Value属性 //控件的当前值 Maximum属性 //ProgressBar正在使用的范围的上限 PerformStep方法 //按照Step属 ...
- E - Polycarp and Snakes
E - Polycarp and Snakes 题意:在一个全是点的图上开始画线,每次将一行或一列任意长度染成字母,一笔染一种字母,字母必须从a开始连续到后面某个字母可以覆盖. 问所给图案是否满足 , ...
- laydate时间控件绑定回调事件
onclick="laydate({istime: true, format: 'YYYY-MM-DD',choose:checkDate});" //回调函数内容 functio ...
- session添加登录次数限制
session 中设置了生存期,20分钟,输入密码错误次数保存到session 中,过一段时间自动解除: //登陆的用户名或者密码出错次数 int n = 0; if(logintimes == nu ...
- js中替换字符串
function formatStr(str){ str=str.replace(/\r\n/ig,"<br/>"); return str; } 要注意两点: 要使用 ...
- 基于idea创建Tomcat远程调试
编辑完catalina文件后重启tomcat
- 基于axios的vue插件,让http请求更简单
ajax-plus 基于axios 的 Vue 插件 如何使用 npm 模块引入 首先通过 npm 安装 ```npm install --save ajax-plus or yarn add aja ...
- ccf 201803-1 跳一跳(Python实现)
一.原题 问题描述 试题编号: 201803-1 试题名称: 跳一跳 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱. 简化 ...
- 初学Python01
1.文本编辑器区别于交互模式的Python,它可以保存Python代码文件,再次打开还是存在.文件保存时要注意是.py的模式. 2.Windows系统下,应使用命令行模式打开.py 首先进入文件所在磁 ...
- drf 频率组件 META字典详情
drf频率组件 什么是频率 控制用户对某个url的请求频率,比如一分钟之内,只能访问三次 自定义频率规则 1.取出访问者ip 2.判断当前ip在不在访问字典中: 不在,则添加进去,返回True; 3. ...