数论<1>——数论基础

这期博客是一个数论入门介绍,dalao们可以自动忽略。

Part 1:素数(质数)

说到数论,小学奥数里也有。我最先想到的就是质数了。素数就是一个只能被1和它自己整除的数。判断的方法也很简单,可以\Theta (n)扫一遍就结束了,但是没必要。由于一个数的因数肯定分布在\Theta (\sqrt{n})的左边和右边。因此,只用扫描到\sqrt{n}就够了。

bool isprime(int n){
	if(n<2)//0和1都不是质数 
		return false;
	for(int i=2;i<=n/i;i++){//这里i<=n/i是一个防止i*i爆int以及sqrt(n)精度不好的小技巧 
		if(n%i==0)
			return false;
	}
	return true;
}

现在,我们知道如何判断一个数是不是质数的方法了。现在,我们向分解G(质因)数。我们\Theta (\sqrt n)的扫描,只要i是n的因数,就把i塞进一个map里,然后除掉n里面所有的i。这样就保证了每个i都是素数,顺便记录次数。最后,有可能n不为0,所以要特判。

map<int,int> fac;//分别是:质因子,次数
for(int i=2;i<=n/i;i++){
	if(n%i==0){
		while(n%i==0){
			n/=i;
			fac[i]++;
		}
	}
}
if(n)//特判
	fac[n]=1;

在这里,我补充几个公式:

唯一分解定理:N=p_{1}^{\alpha _{1}} \cdot p_{2}^{\alpha _{2}} \cdot ......\cdot p_{k}^{\alpha_{k}}

因数个数定理:(\alpha_{1}+1)\cdot (\alpha_{2}+1) \cdot ......(\alpha_{k}+1)

因数和定理:(p_{1}^{0}+p_{1}^{1}+...+p_{1}^{\alpha_{1}})\cdot (p_{2}^{0}+p_{2}^{1}+...+p_{2}^{\alpha_{2}})\cdot ......\cdot (p_{k}^{0}+p_{k}^{1}+...+p_{k}^{\alpha_{k}})

-------------------------------------------------华丽的分割线--------------------------------------------------------

接下来,我们来谈一个比较有意思的东西。首先,如果我让你打印100以内的素数表,你会怎么做?根据刚刚的判断素数的方法,我们可以\Theta (n \sqrt{n})的解决这个问题。但是如果数据放大到10^6甚至10^7,怎么办?

这就要用到素数筛了。素数筛就是一种算法,可以帮你快速筛出素数。有两种筛法,埃筛和欧筛。分别由欧拉和bla~bla~(埃拉托色尼)发明的。先说埃氏筛法(因为好懂),这个算法的核心就是素数的倍数一定是合数。然后,我们就可以愉快的写代码了。

bool isprime[maxn];
void sieve(){
	memset(isprime,true,sizeof(isprime));
  	isprime[0]=isprime[1]=false;
  	for (int i=2;i<=maxn/i;i++){
    	if(isprime[i]){
      		for(int j=i*i;j<=maxn;j+=i)
	  			isprime[j]=false;
	  	}
  	}
}

埃筛的复杂度为\Theta (n \: log \: log \: n),略微有点高,但是好记。

接下来我们来看看复杂度接近\Theta (n)的欧拉筛。埃筛的问题在于素数会被标记多次,那我们优化的方法就是让合数只被标记一次。同时,欧拉筛也叫线性筛(复杂度是线性的嘛)。

bool notprime[maxn];
vector<int> prime;
void sieve(){
	notprime[1]=true;
  	for(int i=2;i<=maxn;i++){
    	if(!notprime[i])
      		prime.push_back(i);
    	for(int x:prime){
      		if(i*x>maxn)
			  	break;
      		notprime[i*x]=true;
      		if(i%x==0)
        		break;
    	}
  	}
}

注意,一定要用notprime,不然又回到埃筛了。

这里就不放例题了,因为其实就是板子。

Part 2:最大公因数和最小公倍数

最大公因数和最小公倍数都是小学奥数学过的东西。但还是稍微介绍一下吧。顾名思义,最大公约数是两个数最大的公约数,最小公倍数是两个数最小的公倍数。接下来,我们来看看如何求最大公约数和最小公倍数。

最大公约数:辗转相除法,即gcd(a,b)=gcd(b,a \: mod \: b) \: (a<b) 。证明嘛,我不大会,但......

OI-Wiki!

放个代码。

int gcd(int a,int b){
    if(b==0)
        return a;
    return gcd(a,b%a);
}
//当然,STL里有一个函数叫__gcd
//它也可以求gcd,所以我们就不用自己写啦(*^▽^*)

顺便说一句,如果gcd(a,b)=1,那我们称a,b互质。欧几里得算法时间复杂度\Theta (log \: max(a,b))

接下来看最小公倍数的求法。先给结论:

int lcm(int a,int b){
    return a*b/__gcd(a,b);
}

为什么?我们令a=p_1^{k_{a_{1}}}\cdot p_2^{k_{a_{2}}}\cdot ...\cdot p_s^{k_{a_{s}}},b=p_1^{k_{b_{1}}}\cdot p_2^{k_{b_{2}}}\cdot ...\cdot p_s^{k_{b_{s}}},那么:

(a,b)=p_1^{min(k_{a_{1}},k_{b_{1}})}\cdot p_2^{min(k_{a_{2}},k_{b_{2}})}\cdot ...\cdot p_s^{min(k_{a_{s}},k_{b_{s}})}

[a,b]=p_1^{max(k_{a_{1}},k_{b_{1}})}\cdot p_2^{max(k_{a_{2}},k_{b_{2}})}\cdot ...\cdot p_s^{max(k_{a_{s}},k_{b_{s}})}

由于k_a+k_b=max(k_a,k_b)+min(k_a+k_b),所以a\times b=lcm(a,b)\times gcd(a,b)

Part 3:扩展欧几里得

我们先来看一个方程:ax+by=c 而它,是终极大Boss。那么它什么时候有解呢?

(a,b)\mid c是,方程有解。So,c必然是gcd(a,b)的倍数。所以,我们先看ax+by=(a,b)的情况,这也是扩展欧几里得解决的问题。

根据欧几里得算法,得ax+by=gcd(a,b)=gcd(a,a \: mod \: b),接下来递归又变成了这个↓

bx+(a \: mod \: b)y=gcd(b, a \: mod \: b)。我们叫这个bx_1+(a \: mod \: b)y_1=gcd(b,a \: mod \: b)

然后就知道ax_0+by_0=bx_1+(a \: mod \: b)y_1,所以x_0=y_1,y_0=x_1-(a*b)/y_1

当你递归到最后一层,也就是b=0的时候,你就解得x'=1,y' \epsilon R。然后我们在向上递归,得出开

始的x和y。Talk is cheap,show me your code.

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

说了这么多,来练练手吧。

P1082:

乍一看,你可能会问:这和扩展欧几里得有啥关系?问的有理,我们来做一些恒等变形。

ax\equiv 1(mod\:b)其实相当于ax+by=1。可这还是跟ax+by=(a,b)不一样啊,没关系。有

解的情况是c\mid gcd(a,b),而1一定满足。现在,它就变成了exgcd的板子题啦!

#include <bits/stdc++.h>
using namespace std;
//exgcd
int main(){
	int a,b,x,y;
	cin>>a>>b;
	int res=exgcd(a,b,x,y);
	if(x<0)
		x+=b;
	cout<<x<<endl;
	return 0;
}

ABC186E:

洛谷上也有。转圈,不难想到同余。

我们可以列出方程S+Kx\equiv 0\: (mod\: N),得Kx\equiv -S\: (mod \: N),再把右边加上N,解x就

ok了。和上一题相似。

#include <bits/stdc++.h>
using namespace std;
long long x,y;
long long exgcd(long long a,long long b){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	long long res=exgcd(b,a%b);
	long long tmp=x;
	x=y;
	y=tmp-a/b*y;
	return res;
}
long long main(){
	int T;
	cin>>T;
	while(T--){
		long long N,S,K;
		cin>>N>>S>>K;
		long long res=exgcd(K,N);
		long long t=(N-S)%N;
		if(t%res)
			cout<<-1<<endl;
		else
			cout<<(x%N+N)%N*(t/res)%(N/res)<<endl;	
	}
	return 0;
}

P1516:

这两个青蛙是真够笨的。

起点是a,b;速度是m,n;步数是t;套圈k次,得(m-n)t-lq=b-a。一个不定方程!所以用扩展

欧几里得算法求解。

//十年OI一场空,不开long long见祖宗
#include <bits/stdc++.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	int res=exgcd(b,a%b,x,y);
	int tmp=x;
	x=y;
	y=tmp-a/b*y;
	return res;
}
int main(){
	int a,b,m,n,l,t,q;
	cin>>a>>b>>m>>n>>l;
	if(m<n){
		swap(m,n);
		swap(a,b);
	}
	int res=exgcd(m-n,l,t,q);
	if((b-a)%res!=0){
		cout<<"Impossible"<<endl;
		return 0;
	}
	int ans=t*(b-a)/res;
	int step=l/res;
	ans%=step;
	if(ans<0)
		ans+=step;
	cout<<ans<<endl;
	return 0;
}

 好了Y(^o^)Y,以上就是本期的全部内容了。我们下期再见!

友情提醒:本期的题解代码都有问题,请不要无脑Ctrl C+Ctrl V

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

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

相关文章

剑指offer JZ23链表中环的入口节点 C++

1、题目描述 2、在VS2019上运行 #include <iostream>using namespace std;struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(NULL) {} };class Solution { public:// 判断链表是否有环&#xff0c;返回相遇的地方ListNode* hasCycle(ListNode* …

Unity 采用自定义通道ShaderGraph实现FullScreen的窗户雨滴效果

效果如下 ShaderGraph实现 N21 随机化 DragLayer分层 将DragLayer分成四层&#xff0c;分别调整每层的缩放和大小 Shader实现的链接&#xff08;Unity 雨水滴到屏幕效果&#xff09; 我也是参考这个实现Shader Graph

markdown页面宽度放宽

变成以上样式 ------------------------------------------------ 然后最后一行加上 #write{ max-width: 90%; } /* 调整源码正文宽度 */ #typora-source .CodeMirror-lines { max-width: 90%; } /* 调整输出 PDF 文件宽度 */ media print { #write{ max-w…

python 基础知识点(蓝桥杯python科目个人复习计划61)

今日复习内容&#xff1a;想到什么复习什么 因为比赛用到的编辑器是IDLE&#xff0c;所以从现在开始&#xff0c;我就不用pycharm了。 例题1&#xff1a; 从1到2020的所有数字中&#xff0c;有多少个2&#xff1f; 这个题是一个填空题&#xff0c;我用的方法是先在编辑器上…

Unity ShaderGraph实现地面积水效果

先看看效果 右侧参数&#xff0c;能够控制水高&#xff0c;波纹的速度等&#xff0c;但是这个效果需要修改高度图和凹凸图&#xff0c;毕竟有些模型并不是平面&#xff0c;对于具有斜面的模型就需要修改贴图。 ShaderGraph如下

【Java Web】秒懂CSS样式!

目录 一、CSS的使用 二、CSS引用方式 三、CSS三大选择器 四、CSS浮动 五、CSS定位 六、CSS盒子模型 一、CSS的使用 css层叠样式表能够对网页中标签元素位置的排版进行像素级别的精确控制&#xff0c;支持几乎所有的字体和字号样式&#xff0c;拥有对网页对象和模型的样式…

一 windso10 笔记本刷linux cent os7.9系统

1:准备材料 16G以上U盘, 笔记本一台 镜像选了阿里云镜像:centos-7-isos-x86_64安装包下载_开源镜像站-阿里云 软件:链接&#xff1a;https://pan.baidu.com/s/13WDp2bBU1Pdx4gRDfmBetg 提取码&#xff1a;09s3 2:把镜像写入U盘,本人已经写入好了,选择镜像,点开始就是,确定等…

基于php的用户登录实现(v2版)(持续迭代)

目录 版本说明 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;login.php 用户欢迎页面&#xff1a;welcome.php 密码修改页面&#xff1a;change_password.html 修改执行&#xff1a;change_password.php 用户注册页面&#xff1a;register.html …

WebGPU vs. 像素流

在构建 Bzar 之前&#xff0c;我们讨论过我们的技术栈是基于在云上渲染内容的像素流&#xff0c;还是基于使用设备自身计算能力的本地渲染技术。 由于这种选择会极大地影响项目的成本、可扩展性和用户体验&#xff0c;因此在开始编写一行代码之前&#xff0c;从一开始就采取正确…

C语言指针、数组学习记录

指针 指针是什么 数据在内存中存放的方式 声明一个变量int i 3;&#xff0c;那么在内存中就会分配一个大小为4字节&#xff08;因为int类型占4字节&#xff09;的内存空间给变量i&#xff0c;这块内存空间存放的数据就是变量i的值。 换句话说就是&#xff0c;在内存中给变…

指针的学习5

目录 sizeof和strlen的区别 sizeof strlen 数组和指针笔试题解析 一维数组 字符数组 二维数组 指针运算笔试题解析 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; sizeof和…

安装配置Hadoop集群

安装配置Hadoop集群的主要步骤 1、安装配置Hadoop 2、配置用户环境变量 3、配置Hadoop 配置core-site.xml文件配置hdfs-site.xml文件配置mapred-site.xml文件配置yarn-site.xml文件配置slaves文件配置hadoop-env.sh文件 更多配置文件的配置信息请参见官方网站的解释。 4、…

vue2中使用异步组件

在大型应用中&#xff0c;我们可能需要将应用分割成小一些的代码块&#xff0c;并且只在需要的时候才从服务器加载一个模块。这时就就可以使用异步组件。 1.通过import方式引入 //组件1<tempalte><Parent v-if"show"></Parent><button clickha…

关于Spring依赖注入简洁方式的探索

最近在项目开发过程中关注到一个依赖注入的写法差异&#xff0c;因为本人代码上有点强迫症&#xff0c;看到这种不同人不一样的写法&#xff0c;特意了解了一下&#xff0c;但是依然有部分疑惑未解。 两种写法&#xff1a;(就是传说中最常见的属性注入和构造函数注入) Service…

云打印机多少钱一台?

随着新的一年的开始&#xff0c;很多同学们都开始打印资料&#xff0c;以应对新一年的各种考试。但是对于学生们来说&#xff0c;去打印店打印价格贵、打印不方便、没时间去打印等多种原因导致我们没办法及时打印资料&#xff0c;这个时候我们就需要用到云打印机。那么云打印机…

浅谈游戏AI LOD的智能控制——LOD交易员

前引 LOD的概念 提到 细节层次 &#xff08;Level of Details&#xff0c;简写LOD&#xff09;&#xff0c;大家可能首先会想到图像渲染&#xff0c;像游戏中大地图的3D物体会随玩家与其距离的远近而变化精度&#xff08;主要是模型面数的变化&#xff0c;有时还会直接剔除&a…

CSS基础知识

font-family: "Trebuchet MS", Verdana, sans-serif; 字体栈&#xff0c;浏览器会一个一个试过去看下哪个可以用 font-size16px; font-size1em; font-size100%;//相对于16px 字体大小&#xff0c;需要进行单位换算16px1em font-weightnormal;//400font-weight属性…

ai直播数字人:AI大模型应用开发的神奇世界

当AI技术的发展走向一个新的高峰&#xff0c;AI直播数字人逐渐成为人们关注的焦点。这种全新的数字人形态&#xff0c;通过大模型应用开发&#xff0c;带来了一个神奇世界。 在这个神奇世界里&#xff0c;AI直播数字人可以展现出与真实人类相媲美的外貌和声音。通过先进的图像…

HarmonyOS ArkTS工程目录结构(Stage模型)

1. ArkTS工程目录结构&#xff08;Stage模型&#xff09; 官方文档&#xff08;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-with-ets-stage-0000001477980905-V2&#xff09; 1.1. AppScope AppScope > app.json5&#xff1a;应用的全局配…

图的单源最短路径问题

目录 一、简述 二、前置配置 三、迪杰斯特拉算法 四、改进的迪杰斯特拉算法 五、贝尔曼福特算法 一、简述 图是一种比较常用的数据结构&#xff0c;将问题转换成图相关的思路也是比较常用的。 图的单源最短路径问题&#xff0c;也就是图中某一个节点到图中其他节点的最短路…