算法竞赛——数论(一),数论内容的介绍,基础数论

文章目录

        • 一, 数论学习路线的介绍和相关建议
          • 1,建议学习人群 :
          • 2,建议学习时长
          • 3,学习路线的介绍
            • 1,基础数论
            • 2,组合数学
            • 3,计算几何
        • 二,基础数论第一部分 —— 快速幂和快速幂矩阵
          • 1,快速幂
            • 1,解题背景
            • 2,思想
            • 3,代码
        • (扩展)矩阵的计算
          • 2,矩阵的快速幂
          • (矩阵)矩阵加速
          • 3,课后例题
            • 1,快速幂专区
            • 2,快速幂矩阵专区

本文在撰写的时候出现了一些小问题,在第一次撰写时没有注意笔记本电量导致直接关机丢失上千字长文 /哭脸/,在此特别提醒大家在学习或者时使用电脑进行生产力活动的时候要及时保存文件🐂。

本文是数论的开篇之章,会有相关数论学习方法和路线的推荐,大家可以借鉴相关思路,下面我们会一点一点进入数论的学习,希望大家能坚持住数论板块的学习,一定会学有所得的!

在这里插入图片描述



慢也好,步子小也好,是在往前走就好。


一, 数论学习路线的介绍和相关建议

本专栏的内容为算法竞赛中的数论内容,来自笔者自身的一些小见解仅作参考,特殊情况应特殊看待。

1,建议学习人群 :

目标赛事奖项为 ICPC区域赛 / 蓝桥杯国赛二等奖以上 / 河北省赛 二等奖以上 ,有一定算法基础并感兴趣的同学(至少要了解一些基础算法)


2,建议学习时长

本专题将会分成四个大部分,建议每一个大部分耗时不要超过20天,总学习时长控制在三个月以内。


3,学习路线的介绍

如下图所示,我们把数论的学习分成了四个板块,由于基础数论的内容非常多,所以在分类的时候我们把基础数论分成了两个板块,分开学习效率更能最大化。

我们在学习数论的前期的时候可以选择性的选择考点比较集中的地方先学习,这样的学习路径可以极大的提高我们的算法实现能力,可以极大的提高我们算法学习的积极性,重点内容 :数论第一阶段,计算几何和组合数学基础内容,按照整个进度学习,虽然体系不完整,但是确实能带来效益的最大化!

当然也可以按照知识体系的顺序学习,这样学习方式比较适合队内的专业数论手,大家可以按照自身的进度调整数论学习路线,下面我们详细的分部分介绍一下所要设计的知识

1,基础数论

首先我们会介绍一下什么是质数,约数,最大公因数… 一些数学定义,在数学中的相关定义和一些取模的技巧的介绍,然后我们就会正式的进入到基础数论的学习中来了,首先是算法竞赛中的快速幂,这个算法结构在算法竞赛中主要用来对一些迭代的程序进行加速的操作!然后我们会介绍一下简单的 GCD和LCM 算法的实现流程,还有素数的筛选,欧拉函数的识别和使用。

第二部分我们主要学习的内容都是和数学中的比较偏门的定理,这块的性价比并不能算的上高,所以这部分的内容可以选择性的跳过,我们只要知道有这个定理,在看题的时候有这么个思路就好,当我们知道这个思路来自数论之后再拿出我们的板子,一般这种题型比较喜欢出现防AK的HANK题中,程度比较弱的同学可以直接跳过。

2,组合数学

组合数学就是我们高中数学中学到的排序和组合问题,只不过会更加的专业,更加的代码化,这部分的内容我认为是比较简单的,尤其是这部分前面的内容,基本就是对高中知识点的复习,这部分题目在贪心题中出现的非常严重,练习这部分的知识,以后就能成为队内的贪心大王,后面的小定理还是了解思路即可,我们目前最主要的方向还是去学习一些简单的知识体系,没有必要去冲击过于困难的内容,毕竟有时候思路出来了,代码手也搓不出来代码

3,计算几何

计算几何整体的难度比较平均,都是中等难度的知识点,建议大家都了解一下,这个对我们对多维图形的模拟很重要,可能会卡在铜牌题的位置,对这部分还是要注意,相关的板子即使背不过,赛时也要带上,我的建议时全部都要了解学习,如果实在是时间有限,可以放弃三维几何部分。

二,基础数论第一部分 —— 快速幂和快速幂矩阵
1,快速幂
1,解题背景

在一般运算中我们可以用循环的方式来求解Nk,但是当这个 K 的数据范围超过 109,以后使用循环求解就显的比较无力了,为了给循环提提速,我们提出了快速幂的思想!

2,思想

快速幂实际上就是使用了二进制的思想进行实现,迭代乘法的方式来实现

3,代码

下面是求解 an 的二次幂代码

typedef long long LL ;
/*
    函数一: fastPow(参数1:表示幂的底数 , 参数2:表示幂的指数 )  
    //  注意数据类型

    函数二 : fastPow(参数1:表示幂的底数 , 参数2:表示幂的指数 , 参数3 : 取模数)
*/
LL fastPow(int a ,int n){
    LL ans = 0 ;
    while(n){
        if(n&1)ans*=a;
        a*=a; n >>= 1 ;
    }
    return ans ; 
}

LL fastPow(LL a ,LL n , LL mod){
    LL ans = 0 ;
    while(n){
        if(n&1) ans*=a,ans%=mod;
        a%=mod,a*=a,a%=mod;
        n>>=1;
    }
    return ans ; 
}

时间复杂度: O(logN)


(扩展)矩阵的计算

在完成了快速幂的讲解之后我们想到了一个问题,这种乘法是知道一个固定的系数的,但是当我们面对更加复杂的矩阵的时候我们应该如何应对?就比如斐波那契数列这种相加关系 An+1 = An + An-1

这叫要使用我们下面的矩阵,为了保护一些没有学线性代数的同学,我们将介绍一些矩阵中简单的规则。


矩阵的加法 : 对应位置直接加减

矩阵的乘法 : 第一个矩阵的第 i 行乘以第二个矩阵的第 j 列,可以得到 Di , j


2,矩阵的快速幂

**思想:**快速幂的思想 + 矩阵的乘法 + 矩阵的结合律

代码:

matrix operator * ( const matrix &a , const matrix &b ){
	matrix c ; 
	memset(c.m,0,sizeof c.m);
	for(int i = 0 ; i < N ; i ++ ){
		for(int j = 0 ; j < N ; j ++ ){
			for(int k = 0 ; k < N ; k ++ ){
				c.m[i][j] = (a.m[i][k] + c.m[i][j] + b.m[k][j]) % mod ; 
			}
		}
	}
	return c ; 
}

matrix pow_matrix(matrix a , int n ){
	matrix ans; 
	memset(ans.m,0,sizeof ans.m);
	for(int i = 0 ; i < N ; i ++ ) ans.m[i][i] = 1 ; 
	while(n){
		if(n&1) ans = ans * a;
		a = a * a ; 
		n >>= 1 ;  
	}
	return ans ; 
}

实际应用 :

  • 斐波那契数列 : 使用矩阵快速幂进行乘法的快速递推能迅速的降低时间复杂度 (本次解题一定要有相关的题解来着重的解释学习的知识占比)
  • 所有多项式中但是有系数关系的知关系都可以使用这种方式尝试实现!

1,计算走 K 次能达到的位置 ,使用 1 / 0 法来进行表示

2,计算走 K 次到达每个点的距离长度

相关的代码可以沿用上文的矩阵中的二次幂来解决问题


(矩阵)矩阵加速

在矩阵中很多的高级用法实际上我们是没有做出相关的解释的,本质上是为了快速幂的知点我们能学习的更加的细致,下面我们来解决的问题是矩阵学习中会涉及到的相关问题,我们学习这部分内容能让我们对矩阵加速有更加详细的认识,相比较而言这部分的定理内容对于有线性代数同学还是比较优待的,话不多说先进入正题:

矩阵加速——矩阵快速幂最常用的算法

矩阵加速算法是一种基于矩阵运算的优化方法,主要用于提高计算效率。矩阵快速幂算法是一种用于高效计算矩阵的高次方的算法。它将朴素的时间复杂度O(n)降到了log(n),从而大大提高了计算效率。

该算法的基本原理是将n个矩阵进行两两分组,然后将每组中的矩阵进行乘法运算,从而得到矩阵的n次方。通过利用矩阵乘法的结合律,可以减少重复计算的次数,进一步提高计算效率。具体实现中,可以将幂次转化为二进制形式,然后根据二进制位进行矩阵的分组和乘法运算。这样可以进一步减少计算量,提高计算效率。

简单的来说矩阵快速幂的原理就是,快速幂思想,矩阵乘法只跟左右顺序有关,和先计算那一部分无关,使用这个原理我们在推导相关的递推公式就可以在我们的矩阵快速幂模板中实现矩阵加速的操作。


3,课后例题
1,快速幂专区

P1226 【模板】快速幂

在这里插入图片描述

题目类型 : 模板题

过题代码:

代码一

#include <iostream>
using namespace std ;
typedef long long LL ;
int main () {
	LL a , b , p ;
	cin >> a >> b >> p ;
	LL c = 1 ; 
	LL aa = a ; 
	LL bb = b ; 
	while(b){
		if(b&1){
			c %= p ;
			c *= a ; 
			c %= p ;
		}
		a %= p ;
		a *= a ;
		a %= p;
		b >>= 1 ;
	}
	cout << aa << "^" << bb << " mod " << p << "=" << c << endl ;
	return 0 ;	
}

代码二

#include <iostream>
using namespace std ;
typedef long long LL ;

LL fastpow(LL a , LL b , LL mod ){
	LL c = 1 ;
	while(b){
		if(b&1){
			c *= a ;
			c %= mod ; 
		}
		b >>= 1 ;
		a %=mod ;
		a *= a ;
		a %=mod;  
	}
	return c ; 
}

int main (){
	LL a , b , c ;
	cin >> a >> b >> c ;
	cout << a << "^" << b << " mod " << c << "=" << fastpow(a,b,c)<< endl;
	return 0 ;
}

快速幂部分的题型一般都是纯粹的板子题,非常的明显,就不过多的扩展介绍了

2,快速幂矩阵专区

快速幂矩阵有一道模板题,我给大家整理出了来,相关的快速幂矩阵的大量的知识为了体现快速幂的思想我们都没有详细的体现,完成这道题目之后我们将会更加详细的介绍

【模板】矩阵快速幂

题目描述

给定 n × n n\times n n×n 的矩阵 A A A,求 A k A^k Ak

输入格式

第一行两个整数 n , k n,k n,k
接下来 n n n 行,每行 n n n 个整数,第 i i i 行的第 j j j 的数表示 A i , j A_{i,j} Ai,j

输出格式

输出 A k A^k Ak

n n n 行,每行 n n n 个数,第 i i i 行第 j j j 个数表示 ( A k ) i , j (A^k)_{i,j} (Ak)i,j,每个元素对 1 0 9 + 7 10^9+7 109+7 取模。

样例 #1

样例输入 #1

2 1
1 1
1 1

样例输出 #1

1 1
1 1

提示

【数据范围】

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\le n \le 100 1n100 0 ≤ k ≤ 1 0 12 0 \le k \le 10^{12} 0k1012 ∣ A i , j ∣ ≤ 1000 |A_{i,j}| \le 1000 Ai,j1000


解题代码

#include <iostream>
#include <cstring>
using namespace std ;
const int N = 110 ;
const int mod = 1e9 + 7 ;    
typedef long long LL ; 
struct matrix {
	LL m[N][N] ; 
};
matrix operator * (const matrix &a , const matrix &b ){
	matrix c ; 
	memset(c.m , 0 , sizeof c.m );
	for(int i = 0 ; i < N ; i ++ ){
		for(int j = 0 ; j < N ; j ++ ){
			for(int k = 0 ; k < N ; k ++ ){
				c.m[i][j] += ((a.m[i][k] % mod) *( b.m[k][j] % mod) %mod); 
				c.m[i][j] %= mod ; 
			}
		}
	}
	return c ; 
} 

matrix pow_matrix ( matrix a , LL b ){
	matrix c ; 
	memset(c.m , 0 , sizeof c.m ) ;
	for(int i = 0 ; i < N ; i ++ ) c.m[i][i] = 1 ; 
	while(b){
		if(b&1){
			c = c * a ;
		}
		a = a * a ; 
		b >>= 1 ; 
	} 
	return c ; 
}

int main () {

	LL n , k ;
	cin >> n >> k ;
	matrix c ; 
	for(int i = 0 ; i < n ; i ++ ){
		for(int j = 0 ; j < n ; j ++ ){
			cin >> c.m[i][j] ; 
		}
	}
	matrix d = pow_matrix(c , k);
	for(int i = 0 ; i < n ; i ++ ){
		for(int j = 0 ; j < n ; j ++ ){
			cout << d.m[i][j] << ' '; 
		}
		cout << endl ;
	}
	return 0 ; 
}

**Div 2 改装题 **

矩阵加速(数列)

题目描述

已知一个数列 a a a,它满足:

a x = { 1 x ∈ { 1 , 2 , 3 } a x − 1 + a x − 3 x ≥ 4 a_x= \begin{cases} 1 & x \in\{1,2,3\}\\ a_{x-1}+a_{x-3} & x \geq 4 \end{cases} ax={1ax1+ax3x{1,2,3}x4

a a a 数列的第 n n n 项对 1 0 9 + 7 10^9+7 109+7 取余的值。

输入格式

第一行一个整数 T T T,表示询问个数。

以下 T T T 行,每行一个正整数 n n n

输出格式

每行输出一个非负整数表示答案。

样例输入 #1

3
6
8
10

样例输出 #1

4
9
19

提示

  • 对于 30 % 30\% 30% 的数据 n ≤ 100 n \leq 100 n100
  • 对于 60 % 60\% 60% 的数据 n ≤ 2 × 1 0 7 n \leq2 \times 10^7 n2×107
  • 对于 100 % 100\% 100% 的数据 1 ≤ T ≤ 100 1 \leq T \leq 100 1T100 1 ≤ n ≤ 2 × 1 0 9 1 \leq n \leq 2 \times 10^9 1n2×109

过题代码

#include <iostream>
#include <cstring>
using namespace std ;
const int N = 5 ;
const int mod = 1e9 + 7 ;    
typedef long long LL ; 
struct matrix {
	LL m[N][N] ; 
};
matrix operator * (const matrix &a , const matrix &b ){
	matrix c ; 
	memset(c.m , 0 , sizeof c.m );
	for(int i = 0 ; i < N ; i ++ ){
		for(int j = 0 ; j < N ; j ++ ){
			for(int k = 0 ; k < N ; k ++ ){
				c.m[i][j] += ((a.m[i][k] % mod) *( b.m[k][j] % mod) %mod); 
				c.m[i][j] %= mod ; 
			}
		}
	}
	return c ; 
} 

matrix pow_matrix ( matrix a , LL b ){
	matrix c ; 
	memset(c.m , 0 , sizeof c.m ) ;
	for(int i = 0 ; i < N ; i ++ ) c.m[i][i] = 1 ; 
	while(b){
		if(b&1){
			c = c * a ;
		}
		a = a * a ; 
		b >>= 1 ; 
	} 
	return c ; 
}
int main () {

	LL n  ;
	cin >> n ;
	matrix c ;
	memset(c.m,0, sizeof c.m);
	c.m[0][0] = 1 ;
	c.m[0][1] = 1 ;
	c.m[0][2] = 1 ;
	matrix a ; 
	memset(a.m,0,sizeof a.m);
	a.m[0][1] = 1 ; 
	a.m[1][2] = 1 ; 
	a.m[2][0] = 1 ; 
	a.m[2][2] = 1 ; 
	while(n--){
		LL k ; 
		cin >> k ;
		if(k==1||k==2){
			cout << 1 << endl ;
			continue ;
		}
		k -= 3 ;

		matrix d = pow_matrix(a,k);
		matrix e = c * d ; 
		cout << e.m[0][2] << endl ; 

	}

	return 0 ; 
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java算法(三): 判断两个数组是否为相等 → (要求:长度、顺序、元素)相等

Java算法&#xff08;三&#xff09; 需求&#xff1a; 1. 定义一个方法&#xff0c;用于比较两个数组是否相同2. 需求&#xff1a;长度&#xff0c;内容&#xff0c;顺序完全相同package com.liujintao.compare;public class SameArray {public static void main (String[] a…

一篇文章让你Docker从入门到精通

一篇文章让你Docker从入门到精通 Docker简介docker的3要素docker安装--centos7示例docker底层原理docker常用命令docker镜像原理数据共享--容器数据卷数据卷容器dockerfile解析Dockerfile实战一 使用dockerfile构建ubuntu镜像&#xff0c;并在里面安装vim及网络工具 一张图展示…

论文阅读:Ensemble Knowledge Transfer for Semantic Segmentation

论文地址&#xff1a;https://ieeexplore.ieee.org/document/8354272 项目及数据地址&#xff1a;https://github.com/ishann/aeroscapes 发表时间&#xff1a;2018年5月7日 语义分割网络通常以严格监督的方式学习&#xff0c;即它们在相似的数据分布上进行训练和测试。在域转…

EPLAN软件中的术语-主数据‘’技术分享

在EPLAN中&#xff0c;主数据(Master Data)这个词被经常、反复地提及&#xff0c;我曾经困惑了很长时间&#xff0c;不得要领。在EPLAN的帮助系统中&#xff0c;它列举了一部分内容&#xff0c;说这些这些就是主数据&#xff0c;但没有解释什么是主数据&#xff0c;除了上面这些…

怎么压缩jpg大小?快来收藏这款jpg压缩工具

不管是工作还是日常生活中&#xff0c;都免不了要用到许多图片&#xff0c;其中jpg图片格式是最常见的一种格式&#xff0c;那么小伙伴们知道怎么将jpg格式压缩大小吗&#xff1f;jpg压缩不仅可以为我们的设备节省空间&#xff0c;还能避免许多对图片大小有限制的平台&#xff…

阿里云双11优惠活动:2核2G3M云服务器1年99元,新老用户均可购买!

阿里云双11优惠活动正在火热进行中&#xff0c;阿里云推出了一款特价云服务器ECS&#xff0c;2核2G3M的配置1年仅需99元&#xff0c;新老用户均可购买&#xff0c;新购、续费同价&#xff01; 活动入口&#xff1a;传送门>>> 活动详情&#xff1a; 云服务器ECS&#…

2023年云计算的发展趋势如何?

混合云的持续发展&#xff1a;混合云指的是将公有云和私有云进行结合&#xff0c;形成一种统一的云计算环境。随着企业对数据隐私和安全性的要求越来越高&#xff0c;以及在数据存储和处理方面的需求不断增长&#xff0c;混合云正在逐渐成为主流。预计未来混合云将会继续保持高…

经典矩阵试题(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、回型矩阵1、题目介绍2、思路讲解3、代码实现4、结果 二、蛇型矩阵1、题目介绍2、思路讲解…

[vue-router]vue3.x Hash路由前缀问题

[vue-router]vue3.x Hash路由前缀问题 问题描述问题分析 问题描述 是在本地开发时&#xff0c;使用的HASH路由&#xff0c;然后在偶然的情况下在/#/前添加了前缀&#xff0c;发现不影响本地的路由的使用&#xff1f;&#xff1f;&#xff1f;&#xff01;&#xff01;&#xf…

chatGPT培训老师AIGC培训讲师叶梓:大模型这么火,我们在使用时应该关注些什么?-6

以下为叶老师讲义分享&#xff1a; P25-P29 提示工程的模式 节省计算资源&#xff1a; 在微调过程中&#xff0c;不需要重新训练整个模型&#xff0c;因此可以节省计算资源。 提高特定任务上的性能&#xff1a; 通过微调&#xff0c;模型可以适应特定任务的语言特征和模式…

怎样在iOS手机上进行自动化测试

Airtest支持iOS自动化测试&#xff0c;在Mac上为iOS手机部署iOS-Tagent之后&#xff0c;就可以使用AirtestIDE连接设备&#xff0c;像连接安卓设备一样&#xff0c;实时投影、控制手机。iOS测试不仅限于真机测试&#xff0c;iOS模拟器也可以进行。Mac端上部署完成后还可以提供给…

linux继续循环案例测试ping网络,目录下的文件权限循环输出

第一&#xff1a;查看本机ip #ip addr 通过脚本访问本机ip1-100&#xff0c;是否可以ping通&#xff0c;并显示结果&#xff0c;上图 知识点 ping -c 数字1 -w 数字1&#xff0c;向目的ip发送1个数据包&#xff0c;等待1秒&#xff0c;无回复中止 &>/dev/null 知…

中远麒麟堡垒机SQL注入漏洞复现

简介 中远麒麟堡垒机用于运维管理的认证、授权、审计等监控管理&#xff0c;在该产品admin.php处存在SQL 注入漏洞。 漏洞复现 FOFA语法&#xff1a; body"url\"admin.php?controlleradmin_index&actionget_user_login_fristauth&username" 或者 c…

Python 爬虫基础

Python 爬虫基础 1.1 理论 在浏览器通过网页拼接【/robots.txt】来了解可爬取的网页路径范围 例如访问&#xff1a; https://www.csdn.net/robots.txt User-agent: * Disallow: /scripts Disallow: /public Disallow: /css/ Disallow: /images/ Disallow: /content/ Disallo…

接口测试总结

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1…

[Day1]工业网络智能控制:三层交换机与防火墙

基础知识点 什么是内网? 内网就是我们平常说的局域网。局域网就是在固定的一个地理区域内由2台以上的电脑用网线和其他网络设备搭建而成的一个封闭的计算机组。它可以是邻居之间的2台电脑&#xff0c;也可以是一幢100层大楼里的1000台电脑。局域网可以是独立封闭运行的&…

开发知识点-stm32/ESP32/Mega2560嵌入式设计

嵌入式设计 STM32四轴飞行器原理图解析小马哥 DragonFly四轴软件开发 13 STM32 SPI总线通讯SPI 总线协议简介SPI 物理层SPI 协议层SPI 通信时序 STM32硬件SPI接口简介SPI接口 利用库函数初始化配置 ESP32 “F:\res\marlin-2.0.x” “F:\res\Marlin-2.1.2” STM32四轴飞行器 小…

FPGA设计过程中有关数据之间的并串转化

1.原理 并串转化是指的是完成串行传输和并行传输两种传输方式之间的转换的技术&#xff0c;通过移位寄存器可以实现串并转换。 串转并&#xff0c;将数据移位保存在寄存器中&#xff0c;再将寄存器的数值同时输出&#xff1b; 并转串&#xff0c;将数据先进行移位&#xff0…

seata事务回滚引起的skywalking数据库存储空间剧增的问题排查

基本信息 产品名称&#xff1a;ATS3.0 问题分类&#xff1a;编码问题 环境类型&#xff1a;环境无关 问题现象 11月1日上午华润DBA收到数据库磁盘空间告警&#xff0c;检查后发现skywalking连接的mysql数据库占用空间从之前一直是比较稳定的&#xff0c;但是10月31日…

绿光集团荣获美业科技创新大奖,杨全军董事长荣获杰出人物

近日&#xff0c;在2023中国&#xff08;南昌&#xff09;国际美发美容节之“凤凰之夜&#xff0c;美业盛典”上&#xff0c;香港绿光国际科技集团股份有限公司董事长杨全军先生荣获了2023年度“凤凰”杰出人物奖。同时&#xff0c;绿光集团也因其研发的AI人工智能数字光磁床、…