BZOJ2242 [SDOI2011]计算器 【BSGS】
2242: [SDOI2011]计算器
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 4741 Solved: 1796
[Submit][Status][Discuss]
Description
Input
输入包含多组数据。
Output
Sample Input
3 1
2 1 3
2 2 3
2 3 3
【样例输入2】
3 2
2 1 3
2 2 3
2 3 3
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
Sample Output
2
1
2
【样例输出2】
2
1
0
K = 1 快速幂
K = 2 exgcd
K = 3 BSGS
前两个就不说了
我们讲讲BSGS【大步小步法】
对于a^x≡b (mod p)
我们设x = i * m - j,【m = √p】
就有(a ^ m) ^ i ≡ b * (a ^ j) (mod p)
j的取值是[0,m-1],i的取值是[1,m]【费马小定理,x一定小于等于p - 1】
我们枚举j放入哈希表,再枚举i,查找有没有对应的j
由于i由小枚举,保证了i * m最小
由于j由小枚举,大的会覆盖小的,所以保证了-j最小
最后的x一定是最小的
什么时候会无解呢?
无解充要条件:gcd(a,p) != 1,且b mod p != 0,也就是a,p不互质
证明:首先p规定是质数了,a与p不互质当且仅当a是p的倍数,此时a mod p = 0,除非b也是p的倍数,否则无解
BSGS算法主要在于减少枚举量,将枚举分解到两侧去,以实现时间的优化
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int T;
LL P;
map<LL,LL> s;
LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1,a = a * a % P)
if (b & 1) ans = ans * a % P;
return ans % P;
}
void exgcd(LL a,LL b,LL& d,LL& x,LL& y){
if (!b){x = 1; y = 0; d = a;}
else exgcd(b,a % b,d,y,x),y -= (a / b) * x;
}
void solve1(){
LL a,b;
while (T--){
a = read(); b = read(); P = read();
printf("%lld\n",qpow(a,b));
}
}
void solve2(){
LL a,c,b,d,x,y,b0;
while (T--){
a = read(); c = read(); b = read();
exgcd(a,b,d,x,y);
if (c % d != 0) puts("Orz, I cannot find x!");
else {
x *= c / d; b0 = b / d;
printf("%lld\n",(x % b0 + b0) % b0);
}
}
}
void solve3(){
LL a,b,m,ans,t;
while (T--){
a = read(); b = read(); P = read(); ans = -1;
s.clear(); m = (LL)sqrt(P); t = qpow(a,m);
if (a % P == 0){
if (b % P == 0) puts("1");
else puts("Orz, I cannot find x!");
continue;
}
for (LL i = 0; i < m; i++) s[b * qpow(a,i) % P] = i;
for (LL i = 0; i <= m; i++){
LL tmp = qpow(t,i);
if (s.count(tmp)){
ans = i * m - s[tmp]; break;
}
}
if (ans == -1) puts("Orz, I cannot find x!");
else printf("%lld\n",ans);
}
}
int main(){
T = read(); int t = read();
if (t == 1) solve1();
else if (t == 2) solve2();
else solve3();
return 0;
}
BZOJ2242 [SDOI2011]计算器 【BSGS】的更多相关文章
- bzoj2242: [SDOI2011]计算器 BSGS+exgcd
你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值:(快速幂) 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数:(exgcd) 3.给 ...
- bzoj2242: [SDOI2011]计算器 && BSGS 算法
BSGS算法 给定y.z.p,计算满足yx mod p=z的最小非负整数x.p为质数(没法写数学公式,以下内容用心去感受吧) 设 x = i*m + j. 则 y^(j)≡z∗y^(-i*m)) (m ...
- bzoj2242 [SDOI2011]计算器——BSGS
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2242 第一次写BSGS,参考了好多好多博客: 然而看到的讲解和模板是一种写法,这道题的网上题 ...
- 【BZOJ2242】[SDOI2011]计算器 BSGS
[BZOJ2242][SDOI2011]计算器 Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ ...
- [bzoj2242][Sdoi2011]计算器_exgcd_BSGS
计算器 bzoj-2242 Sdoi-2011 题目大意:裸题,支持快速幂.扩展gcd.拔山盖世 注释:所有数据保证int,10组数据. 想法:裸题,就是注意一下exgcd别敲错... ... 最后, ...
- bzoj 2242: [SDOI2011]计算器 BSGS+快速幂+扩展欧几里德
2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 你被 ...
- BZOJ2242[SDOI2011]计算器——exgcd+BSGS
题目描述 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给定y,z,p, ...
- 【数学 BSGS】bzoj2242: [SDOI2011]计算器
数论的板子集合…… Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最 ...
- 【数论】【快速幂】【扩展欧几里得】【BSGS算法】bzoj2242 [SDOI2011]计算器
说是BSGS……但是跟前面那题的扩展BSGS其实是一样的……因为模数虽然是质数,但是其可能可以整除a!!所以这两者其实是一样的…… 第一二种操作不赘述. #include<cstdio> ...
随机推荐
- 40套PSD欧美扁平化网页模板,可二次编辑开发,精品
40套PSD欧美扁平化网页模板,可二次编辑开发,绝对精品,下载地址:百度网盘, https://pan.baidu.com/s/1uMF4MM_3UC2Q6mbyNomLfQ 模板内容预览: 小
- Windows运行机理——消息与消息队列
Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 Windows程序设计时一种基于消息的时机驱动方式的设计模式,完全不同 ...
- unity中虚拟摇杆的实现
实现效果: 实现: 使用NGUI添加虚拟摇杆背景和其子物体按钮,为按钮Attach boxcollider和ButtionScript.为按钮添加如下脚本: 注意:其中的静态属性可以在控制物体移动的 ...
- leetcode-累加数(C++)
累加数是一个字符串,组成它的数字可以形成累加序列. 一个有效的累加序列必须至少包含 3 个数.除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和. 给定一个只包含数字 '0'-'9' ...
- python numpy数据相减
numpy数据相减,a和b两者shape要一样,然后是对应的位置相减.要不然,a的shape可以是(1,m),注意m要等于b的列数. import numpy as np a = [ [0, 1, 2 ...
- HTML/JSP中一些单书名号标签的用途<%-- --%><!-- --><%@ %><%! %><% %><%= %>
注释 <%-- --%>是(JSP)隐式注释,不会在页面显示的注释 <!-- -->是(Html)显示注释,会在JSP页面显示 关于注释还有单行隐式注释//和多行隐式注释/* ...
- [转载]启动tomcat时,一直卡在Deploying web application directory这块的解决方案
转载:https://www.cnblogs.com/mycifeng/p/6972446.html 本来今天正常往服务器上扔一个tomcat 部署一个项目的, 最后再启动tomcat 的时候 发现项 ...
- ajax获取动态列表数据后的分页问题
ajax获取动态列表数据后的分页问题 这是我在写前台网站时遇到的一个分页问题,由于数据是通过ajax的方式来请求得到的,如果引入相应的js文件来做分页,假如只是静态的填放数据到列表各项内容中(列表条数 ...
- 官方文档 恢复备份指南二 Getting Started with RMAN
本章对RMAN进行基本的熟悉和了解 1.Overview of the RMAN Environment RMAN运行时需要的最小环境: target database ...
- 《javascript模式--by Stoyan Stefanov》书摘--函数
三.函数 1.函数的命名属性 // IE下不支持name属性 var foo = function bar () { // todo }; foo.name; // "bar" 2 ...