数论——拓展欧几里德算法复习

news2024/11/14 15:13:02

最近也是在备战比赛,所以也是来小小的复习了一下以前学的东西

最重要的是第一道题!

最重要的是第一道题! 

最重要的是第一道题!

先放拓欧板子(不懂怎么推出了就发在评论区或者私聊)

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int x2,y2;
	int d=exgcd(b,a%b,x2,y2)
	x=y2;
	y=x2-a/b*y2;
	return d;
}

例题:

P2054 [AHOI2005] 洗牌

 我们先来通过6张牌来列举一下

初始        [  1 , 2 , 3 , 4 , 5 , 6  ]

第一次    [  4 , 1 , 5 , 2 , 6 , 3  ]

第二次    [  2 , 4 , 6 , 1 , 3 , 5  ]

第三次   [  1 , 2 , 3 , 4 , 5 , 6  ]

我们通过上面对1这个数据分析,

初始值在1位置,第一次变换后在2位置,第二次变换后在4位置,第三次变换后在1位置

我们发现每次都相当于乘2,但是为什么会被突然折断呢?我们不难想到可能是存在取模操作

因此我们可以大胆猜想这个数是7,也就是(n+1)

我们再对3这个数据进行分析

初始值在3位置,第一次在6位置,第二次再5位置,第三次在3位置

我们发现也是每次位置都乘2,然后取模7(n+1)

因此我们就发现了规律

第i个数m次操作后的位置为 :( i* 2^m)%(n+1)

但是题意问的是m次操作之后,谁在L这个位置,不是问你每个数在哪,而是问你在特定位置的数,很明显,我们一开始想的是遍历一遍所有数,找到谁在那个位置,但是数据是10^10,很明显会超时,因此我们只能去倒推一遍 这个式子

假设x在L那个位置,那么

(2^m)*x= (n+1) *k + L 

请问你看这个式子想到了什么???

我嘞个豆,啥也没想到,你是要毁了我吗?孩子

那我再给你将这个式子变一下形式

(2^m)*x + (n +1) *y =  L  这下能看出来拓展欧几里得的形式了吧

为什么能用拓欧呢?因为题目上说了,n是一个偶数,n+1一定是个奇数,2^m次方一定是个偶数,所以肯定互质的

但是这个式子也很麻烦,能不能再变一下呢?那肯定是可以的

我们先去求 

(2^m)*x + (n +1) *y =  1,然后最后给x乘以L不就是了,说罢,我的气息终于不再掩饰,顷刻将代码炼化出来

77pts

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  

int n, m, l;  
int mod;  

int fast(int a, int b, int mod) 
{  
    int result = 1;  
    int base = a % mod;   
    while (b > 0) 
	{  
        if (b % 2 == 1) 
		{  
            result = (result * base) % mod;  
        }  
        base = (base * base) % mod;  
        b /= 2;  
    }  
    return result;  
}  

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

signed main() {  
    ios_base::sync_with_stdio(0);  
    cin.tie(0);  
    cout.tie(0);  

    cin >> n >> m >> l;  
    mod = n + 1;   
    int x, y;  
    int f = fast(2, m, mod);
    int z = exgcd(f, mod, x, y); 
    x = (x+mod) % mod; 
    cout << (x*l) % mod << '\n'; 
} 

 没想到被暗算了,在运算过程中有可能会导致超出long long的范围,因此需要用到龟速幂,也就是在乘法的过程中用快速乘去运算 

84pts

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  

int n, m, l;  
int mod;  


int mul(int a,int b)
{
	int result=0;
	while(b>0)
	{
		if(b%2==1)
		{
			result=(result+a)%mod;
		}
		a=(a+a)%mod;
		b/=2;
	}
	return result%mod;
}

int fast(int a, int b) 
{  
    int result = 1;  
    int base = a % mod;   
    while (b > 0) 
	{  
        if (b % 2 == 1) 
		{  
            result=mul(result,base);
        }  
        base = mul(base,base);  
        b /= 2;  
    }  
    return result%mod; 
}  


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

signed main() {  
    ios_base::sync_with_stdio(0);  
    cin.tie(0);  
    cout.tie(0);  

    cin >> n >> m >> l;  
    mod = n + 1;   
    int x, y;  
    int f = fast(2, m);
    int z = exgcd(f, mod, x, y); 
    x = (x+mod) % mod; 
    cout << (x*l) % mod << '\n'; 
} 

为什么还是错一个点嘞?左思右想都没想明白,

才发现,在逆元前面还是有可能会爆数据,为什么不能用乘法逆元的积性函数的性质,我先去求2和n+1的逆元然后再去m次方后再去乘以L,思考便后,我便不再掩饰自己的气息,仿佛有成尊之势

果然AC了

100pts

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  

int n, m, l;  
int mod;  

int mul(int a,int b)
{
	int result=0;
	while(b>0)
	{
		if(b%2==1)
		{
			result=(result+a)%mod;
		}
		a=(a+a)%mod;
		b/=2;
	}
	return result%mod;
}

int fast(int a, int b) 
{  
    int result = 1;  
    int base = a % mod;   
    while (b > 0) 
	{  
        if (b % 2 == 1) 
		{  
            result=mul(result,base);
        }  
        base = mul(base,base);  
        b /= 2;  
    }  
    return result%mod; 
}  


int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int x2,y2;
	int d=exgcd(b,a%b,x2,y2);
	x=y2;
	y=x2-a/b*y2;
	return d;
}

signed main() 
{  
    ios_base::sync_with_stdio(0);  
    cin.tie(0);  
    cout.tie(0);  
    
    cin >> n >> m >> l;  
    mod = n + 1;   
    int x, y;  
    exgcd(2, mod, x, y); 
    x = (x+mod) % mod; 
    x=fast(x,m);
    cout<<mul(x,l) << '\n'; 
} 

P5656 【模板】二元一次不定方程 (exgcd)

思路:题目不是很难,但是处理的条件颇多,只要有耐心并且细心一点都可以写出来

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int a,b,c;
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int x2,y2;
	int d=exgcd(b,a%b,x2,y2);
	x=y2;
	y=x2-a/b*y2;
	return d;
}
signed main()
{
	cin>>t;
	while(t--)
	{
		int x,y;
		int d;
		int minnx,minny,maxnx,maxny;
		int cnt=0;
		cin>>a>>b>>c;
		d=gcd(a,b);
		if(c%d!=0)
		{
			cout<<-1<<"\n";
		}
		else
		{
			a/=d,b/=d,c/=d;
			exgcd(a,b,x,y);
			x*=c,y*=c;
			if(x>0&&x%b!=0)
			{
				minnx=x%b;
			}
			else
			{
				minnx=x%b+b;
			}
			maxny=(c-minnx*a)/b;
			if(y>0&&y%a!=0)
			{
				minny=y%a;
			}
			else
			{
				minny=y%a+a;
			}
			maxnx=(c-minny*b)/a; 
			if(maxnx>0)
			{
				cnt=(maxnx-minnx)/b+1;
			}
			if(cnt==0)
			{
				cout<<minnx<<" "<<minny<<"\n"; 
			}
			else
			{
				cout<<cnt<<" "<<minnx<<" "<<minny<<" "<<maxnx<<" "<<maxny<<"\n";
			}
		}
	}
	return 0;
}

 P1516 青蛙的约会

思路:这题我们可以写出一个方程

假设第一只青蛙的起始位置为n,速度为a,第二只青蛙的起始位置为m,速度为b 

可以写出方程

(a-b)*t+L *y=m-n

想到了什么?当然是拓欧

直接去写拓欧去求出最小的x,然后x*(m-n)/gcd(a-b,L)即可,当然不要忘记取模L

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a,b,l;
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	int x2,y2;
	int d=exgcd(b,a%b,x2,y2);
	x=y2;
	y=x2-a/b*y2;
	return d;
}

signed main()
{
	int x,y;
	cin>>n>>m>>a>>b>>l;
	if(a<b)
	{
		swap(a,b),swap(n,m);
	}
	a=a-b;
	b=l;
	int d=gcd(a,b);
	int c=(m-n+l)%l;
	exgcd(a,b,x,y);
	if(c%d!=0)
	{
		cout<<"Impossible\n";
		return 0;
	}
	l/=d;
	cout<<(c/d*x%l+l)%l;
	return 0;
}

P3951 [NOIP2017 提高组] 小凯的疑惑

思路:其实就是看自己的思维的,如果想要能够被表示那么就说明x和y都要大于0,所以不能表示的最小数一定为

-a+?*b(?表示现在还不知道)

那为什么一定为这种形式呢?

x不能等于-2吗?

肯定可以啊,只不过一定不是最大,因为还有一个x=-1的时候更大

那么?的范围是什么,最大是(a-1) 

为什么呢?假如可以为a的话,那么方程就可以化简为a*(b-1),那么就可以用a类型钞票单独表示了

最后就可以写出-a+b*(a-1)

也就是a*b-a-b;

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
	int a,b;
	cin>>a>>b;
	cout<<(a*b-a-b);
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2101988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

s3fs的使用

s3fs是一个将s3服务器上的桶映射为本地目录的程序。 项目源码位于&#xff1a; https://github.com/s3fs-fuse/s3fs-fuse 这是一个比较长期的项目了&#xff0c;现在在大数据领域S3协议基本上已经成为最通用的协议。 各大云平台&#xff0c;什么阿里云&#xff0c;某为云&am…

初识Linux · 有关makefile

目录 前言&#xff1a; 1 makefile的简单使用 2 makefile介绍 前言&#xff1a; 我们上文介绍了gcc和g的基本使用&#xff0c;带了许多的子指令&#xff0c;但是有的时候啊&#xff0c;一个一个敲指令确实有点麻烦了&#xff0c;此时&#xff0c;一个工具就能派上用场&…

DDD设计方法-3-仓储,封装持久化数据

前情提要&#xff1a;一共包含 如下六篇文章&#xff08;篇幅精简&#xff0c;快速入门&#xff09; 1、初识DDD 2、聚合、实体、值对象 3、仓储&#xff0c;封装持久化数据 4、端口和适配器 5、领域事件 6、领域服务&#xff0c;实现约定 DDD设计方法-3-仓储&#xff0c;封装…

计算机网络 第2章 物理层

文章目录 通信基础基本概念信道的极限容量编码与调制常用的编码方法常用的调制方法 传输介质双绞线同轴电缆光纤以太网对有限传输介质的命名规则无线传输介质物理层接口的特性 物理层设备中继器集线器一些特性 物理层任务&#xff1a;实现相邻节点之间比特&#xff08;0或1&…

后端MVC三层架构,Mybatis ,雪花算法生成唯一id

一.MVC MVC(Model View Controller)&#xff0c;它是一种思想&#xff0c;他把软件系统分为 以下三部分&#xff1a; Model(模型)&#xff1a;用来处理程序中数据逻辑的部分&#xff08;service&#xff0c;dao层&#xff09; View(视图)&#xff1a;在应用程序中&#xff0…

如何把逆地理编码结果表格的不同字段都作为点标注的属性

0.序 很多行业都需要获取一些地点的信息作为gis基础数据。 如消防行业的重点建筑 交通行业的道路 智慧城市的商业楼栋等等。 这些表格信息如何叠加到地图之上&#xff0c;并能够很好的查看各个字段的信息&#xff1f; 本文的重点是把经纬度坐标的Excel表格内容转成kml&…

【Python】数据分析分类图可视化

目录 条形图 箱形图 散点图 分簇散点图 小提琴 分簇小提琴 条形图 条形图是一种直观的图表形式&#xff0c;它通过不同长度的矩形条&#xff08;即“条形”&#xff09;来展示数值变量的中心趋势估计值&#xff0c;其中每个矩形的高度直接对应于该组数据的某个中心量度&…

保存json时,保存成自己喜欢的格式的方法(而不是直接保存成格式化的json文档)

保存json时&#xff0c;不是直接保存成格式化的json文档的格式的方法 前言&#xff0c;博主是如何把格式话的json格式保存成自己喜欢的json格式的保存成格式化的json文档的格式&#xff1a;带缩进格式全部保存成一行每条数据保存成一行&#xff1a; 保存成自己喜欢的格式碎碎念…

《Rust避坑入门记》第1章:挖数据竞争大坑的滥用可变性

赵可菲是一名Java程序员&#xff0c;一直在维护一个有十多年历史的老旧系统。这个系统即将被淘汰&#xff0c;代码质量也很差&#xff0c;每次上线都会出现很多bug&#xff0c;她不得不加班修复。公司给了她3个月的内部转岗期&#xff0c;如果转不出去就会被裁员。她得知公司可…

奇安信天眼--探针/分析平台部署及联动

奇安信天眼–探针/分析平台部署及联动 一 概述二 探针/分析平台部署及联动 1.网络拓扑2.配置流量传感器&#xff08;探针&#xff09; (1)登录控制台(2)配置接口(3)配置默认路由及DNS(4)配置SNMP(5)在探针联动分析平台 3.配置分析平台 (1)登录控制台(2)配置接口(3)配置默认路由…

2024年全国各省路网矢量数据介绍

一、2024年全国路网矢量数据介绍 数据更新时间&#xff1a;2024年5月 数据范围&#xff1a;全国&#xff08;不包含台湾省&#xff09; 数据格式&#xff1a;shp&#xff08;线&#xff09; 数据包含类型&#xff1a;城市主干道、城市次干道、城市快速路、城市支路、高速公…

Python编码系列—Python代码审查的艺术:提升代码质量的黄金法则

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

苹果录屏功能究竟何在?深入探寻苹果设备上的录屏功能:简便、高效、一键达成

在当下这一数字化的时代&#xff0c;不论是教学演示&#xff0c;还是游戏分享&#xff0c;抑或是工作汇报&#xff0c;录屏软件皆已成为我们日常生活中不可或缺之工具。苹果设备以其出类拔萃的用户体验而声名远播&#xff0c;而其内置的录屏功能更是将便捷性与功能性精妙融合。…

TensorFlow介绍二-线性回归案例

一.案例步骤 1.准备数据集&#xff1a;y0.8x0.7 100个样本 2.建立线性模型&#xff0c;初始化w和b变量 3.确定损失函数&#xff08;预测值与真实值之间的误差&#xff09;&#xff0c;均方误差 4.梯度下降优化损失 二.完整功能代码&#xff1a; import os os.environ[TF…

前端脚手架,自动创建远程仓库并推送

包含命令行选择和输入配置&#xff0c;远程仓库拉取模板&#xff0c;根据配置将代码注入模板框架的代码中&#xff0c;自动创建远程仓库&#xff0c;初始化git并提交至远程仓库&#xff0c;方便项目开发&#xff0c;简化流程。 目录结构 创建一个bin文件夹&#xff0c;添加ind…

KAN 学习 Day2 —— utils.py及spline.py 代码解读及测试

在KAN学习Day1——模型框架解析及HelloKAN中&#xff0c;我对KAN模型的基本原理进行了简单说明&#xff0c;并将作者团队给出的入门教程hellokan跑了一遍&#xff0c;今天我们直接开始进行源码解读。 目录 一、kan目录 二、utils.py 2.1 导入库和模块 2.2 逆函数定义 2.3 …

CentOS 7安装Docker详细步骤-无坑-丝滑-顺畅

一&#xff0c;安装软件包 yum install -y yum-utils device-mapper-persistent-data lvm2二&#xff0c;更换yum源为阿里源&#xff1a; yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 三&#xff0c;查看docker版本&…

标准库标头 <optional> (C++17)学习之optional

类模板 std::optional 管理一个可选 &#xfeff;的所含值&#xff0c;即既可以存在也可以不存在的值。 一种常见的 optional 使用情况是作为可能失败的函数的返回值。与如 std::pair<T, bool> 等其他手段相比&#xff0c;optional 可以很好地处理构造开销高昂的对象&a…

【科普】双轴测径仪是根据哪个测量值控制外径尺寸?

单轴测径仪与双轴测径仪都是自带闭环控制功能的在线外径测量设备&#xff0c;单轴测径仪只有一个测头&#xff0c;是根据该测头的检测数据进行控制&#xff0c;这点毋庸置疑&#xff0c;那双轴测径仪这种具备两组测头的设备又是如何控制的&#xff0c;本文就来简单的介绍一下。…

Ubuntu安装网卡驱动

没有无线网 给自己装了双系统后&#xff0c;发现没有无线网络 下载驱动文件 打开终端&#xff0c;输入 lspci -k 能看到&#xff0c;虽然我是RTL8125BG&#xff0c;但use的是r8169: 08:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controll…