洛古题面

对于操作一,用快速幂算即可

代码如下

int quickpow(int a,int b,int k)
{
int r=1;
while(b)
{
if(b&1) r=(r*a)%k;
b>>=1;
a=(a*a)%k;
}
return r;
}

对于操作二,用拓展欧几里得算法即可。

已知\(a,b,n\),求\(x\)的最小值,使得\(a*x≡b(mod p)\),可以转化为:\(a*x+p*y=b\),则要求\(gcd(a,n)|b\),否则无解。不定方程的求法可以参照这道题

\(exgcd\)代码如下

int exgcd(int a,int b,int&x,int&y)
{
if(!b)
{
x=1,y=0;
return a;
}
re int gcd=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}

对于操作三,我们需要用到一个新的算法B(拔)S(山)G(盖)S(世),他可以快速的求出求,满足\(a^x ≡ b(mod p)\)的最小的非负整数\(x\)。

求法是将\(x\)拆分成\(i*m-j\)的形式(其中\(m\)为\(sqrt(p)\)向上取整的值,则原式化为\(a^{i*m-j} ≡ b(mod p)\)。

移向后得\(a^{i*m} ≡ b*a^j(mod p)\)

我们从\(0-m\)枚举\(j\),并将\(b*a^j\)的所有值存入哈希表中

接着在从\(1-m\)枚举\(i\),算出所有的\(a^{i*m}\)

如果一个i对应的\(a^{i*m}\)的值已经在哈希表中,则表明i*m-j为一个解,输出此时的解即可

因为j<=m,所以求出的解随i的增大而减小,所以最先求出的i所对的解,即为所求。

	re int y=read(),z=read(),p=read();
re int m=ceil(sqrt(p));
if(y%p==0&&z)
{
puts("Orz, I cannot find x!");
continue;
}
//这里要特判,因为如果y%p==0了,那么不管x取何值,(y^x)%p一定为0。
a.clear();
re int now=z%p,f=quickpow(y,m,p);
a[now]=0;
for(re int i=1;i<=m;++i)
{
now=(now*y)%p;
a[now]=i;
}
now=1;
re int flag=1;
for(re int i=1;i<=m;++i)
{
now=(now*f)%p;
if(a[now])
{
re int ans=(i*m-a[now])%p;
printf("%lld\n",(ans+p)%p);
flag=0;
break;
}
}
if(flag) puts("Orz, I cannot find x!");

所有代码如下:

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define int long long
map<int,int>a;
il int read()
{
re int x=0,f=1;re char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return x*f;
}
il int quickpow(int a,int b,int k)
{
re int r=1;
while(b)
{
if(b&1) r=(r*a)%k;
b>>=1;
a=(a*a)%k;
}
return r;
}
il int exgcd(int a,int b,int&x,int&y)
{
if(!b)
{
x=1,y=0;
return a;
}
re int gcd=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}
signed main()
{
re int T=read(),k=read();
if(k==1)
{
while(T--)
{
re int y=read(),z=read(),p=read();
printf("%lld\n",quickpow(y,z,p));
}
}
else if(k==2)
{
while(T--)
{
re int a=read(),b=read(),p=read(),x,y;
re int gcd=exgcd(a,p,x,y);
if(b%gcd) puts("Orz, I cannot find x!");
else
{
re int temp=p/gcd;
while(x<0) x+=temp;
printf("%lld\n",((x*b/gcd)%temp+temp)%temp);
}
}
}
else
{
while(T--)
{
re int y=read(),z=read(),p=read();
re int m=ceil(sqrt(p));
if(y%p==0&&z)
{
puts("Orz, I cannot find x!");
continue;
}
a.clear();
re int now=z%p,f=quickpow(y,m,p);
a[now]=0;
for(re int i=1;i<=m;++i)
{
now=(now*y)%p;
a[now]=i;
}
now=1;
re int flag=1;
for(re int i=1;i<=m;++i)
{
now=(now*f)%p;
if(a[now])
{
re int ans=(i*m-a[now])%p;
printf("%lld\n",(ans+p)%p);
flag=0;
break;
}
}
if(flag) puts("Orz, I cannot find x!");
}
}
return 0;
}

[SDOI2011]计算器(BSGS)的更多相关文章

  1. bzoj 2242: [SDOI2011]计算器 BSGS+快速幂+扩展欧几里德

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 你被 ...

  2. 【BZOJ2242】[SDOI2011]计算器 BSGS

    [BZOJ2242][SDOI2011]计算器 Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ ...

  3. bzoj2242: [SDOI2011]计算器 BSGS+exgcd

    你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值:(快速幂) 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数:(exgcd) 3.给 ...

  4. bzoj2242: [SDOI2011]计算器 && BSGS 算法

    BSGS算法 给定y.z.p,计算满足yx mod p=z的最小非负整数x.p为质数(没法写数学公式,以下内容用心去感受吧) 设 x = i*m + j. 则 y^(j)≡z∗y^(-i*m)) (m ...

  5. BZOJ 2242 [SDOI2011]计算器 | BSGS

    insert的时候忘了取模了-- #include <cstdio> #include <cmath> #include <cstring> #include &l ...

  6. bzoj 2242 [SDOI2011]计算器——BSGS模板

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2242 第一道BSGS! 咳咳,我到底改了些什么?…… 感觉和自己的第一版写的差不多……可能是 ...

  7. bzoj2242 [SDOI2011]计算器——BSGS

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2242 第一次写BSGS,参考了好多好多博客: 然而看到的讲解和模板是一种写法,这道题的网上题 ...

  8. BZOJ 2242 [SDOI2011]计算器 BSGS+高速幂+EXGCD

    题意:id=2242">链接 方法: BSGS+高速幂+EXGCD 解析: BSGS- 题解同上.. 代码: #include <cmath> #include <c ...

  9. BZOJ 2242 / Luogu P2485 [SDOI2011]计算器 (BSGS)

    type 1type\ 1type 1 就直接快速幂 type 2type\ 2type 2 特判+求逆元就行了. type 3type\ 3type 3 BSGS板 CODE #include< ...

  10. bzoj 2242: [SDOI2011]计算器 & BSGS算法笔记

    这题的主要难点在于第三问该如何解决 于是就要知道BSGS是怎样的一种方法了 首先BSGS是meet in the middle的一种(戳下面看) http://m.blog.csdn.net/blog ...

随机推荐

  1. window端编码到Linux允许脚本 笔记

    昨天升级一个服务,发现没有现成的启动脚本.就随手写了一个,一运行发现不行.竟然报错说找不到文件,No such file or directory [nohup: cannot run command ...

  2. 解读event.returnValue和return false

    前言 首先我们要清楚returnValue是IE的一个属性,如果设置了该属性,它的值比事件句柄的返回值优先级要高,把它的值设置为false,可以取消发生事件源元素的默认动作:return false就 ...

  3. Python深入类和对象

    一. 鸭子类型和多态 1.什么是鸭子类型: 在程序设计中,鸭子类型(英语:Duck typing)是动态类型和某些静态语言的一种对象推断风格."鸭子类型"像多态一样工作,但是没有继 ...

  4. fiddler学习笔记2 字段说明;移动设备、解密证书

    # :           抓取顺序从1开始递增 result:    http 请求状态 protocol:   请求使用的协议如:http https ftp Host:         请求地址 ...

  5. 【python练习题】程序15

    #题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示. n = input('请输入成绩 :') n = int(n) if ...

  6. 安装 BizTalk Server 2016

    在单台计算机上安装 BizTalk Server. 开始操作之前       系统管理员 – 安装 SQL Server 时,安装程序会自动向登录的帐户授予系统管理员权限. 由于安装 BizTalk ...

  7. JS 强制类型转化

    在Js中, 强制类型转化分为两种情况: 一种是引用类型转化基本类型, 如数组转化成数字:一种是两种不同基本类型之间的转化,如字符串转化为数字.你不能将基本类型转化成引用类型,比如,不可能把数字转化为数 ...

  8. BZOJ 1443 游戏(二分图博弈)

    新知识get. 一类博弈问题,基于以下条件: 1.博弈者人数为两人,双方轮流进行决策.2.博弈状态(对应点)可分为两类(状态空间可分为两个集合),对应二分图两边(X集和Y集).任意合法的决策(对应边) ...

  9. IntelliJ IDEA default settings 全局默认设置

    可以通过以下两个位置设置IDEA的全局默认设置: 以后诸如默认的maven配置就不需要每次都重复配置了?

  10. random 随机数模块

    import random # 随机数模块 print(random.random()) #0-1 不包括1随机浮点数 print(random.randint(1,10)) # 1-10 包括1和1 ...