首页 > 其他分享 >基础数论

基础数论

时间:2024-06-22 15:32:03浏览次数:4  
标签:prime 约数 数论 合数 基础 sqrt int 素数

素数

素数和合数

定义

若 \(p \in \Zeta\),且 \(p \not= 0, \pm1\),其约数集合中的元素只有 \(1\) 和 \(p\) 本身,那么称 \(p\) 为素数。

若 \(a \in \Zeta\),且 \(a \not= 0, \pm1\), \(a\) 不为素数,则为合数。

素数一般指正的素数。

素数计数

\(\pi(x)\) 表示小于或等于 \(x\) 的素数个数。随 \(x\) 增大,近似结果:

\(\pi(x) \sim \frac{x}{\ln(x)}\)。

素数判定

试除。枚举 \(1 \sim \sqrt{n}\) 整数,看是否能够整除。

bool isPrime(a) {
  if (a < 2) return 0;
  for (int i = 2; i * i <= a; ++i)
    if (a % i == 0) return 0;
  return 1;
}

素数筛法

  1. 埃氏筛。

对于任意大于 \(1\) 的正整数 \(n\) ,那么它的 \(x\) 倍为合数\((x > 1)\)。

如果我们从小到大考虑每个数,然后同时把当前这个数的所有(比自己大的)倍数记为合数,那么运行结束的时候没有被标记的数就是素数了。

vector<int> prime;
bool is_prime[N];

void Eratosthenes(int n) {
  is_prime[0] = is_prime[1] = false;
  for (int i = 2; i <= n; ++i) 
      is_prime[i] = true;
  int x = sqrt(n);
  for (int i = 2; i <= x; ++i) {
    if (is_prime[i])
      for (int j = i * i; j <= n; j += i) 
          is_prime[j] = false;
  }
  for (int i = 2; i <= n; ++i)
    if (is_prime[i]) 
        prime.push_back(i);
}

时间复杂度为 \(\Omicron(n \log \log n)\)。

线性筛

可以注意到, 埃氏筛法仍有优化空间,它会将一个合数重复多次标记。

让每个合数都只被标记一次即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e8+10;
const int maxm = 1e7;
int v[maxn],prime[maxm]; // v[i] 表示 i 的最小质因子
int n, q, cnt=0;

void is_prime() { // 线性筛
	memset(v, 0, sizeof(v));
	for(int i=2; i<=n; ++i) {
		if( !v[i] ) {
			v[i] = i;
			prime[++cnt] = i;
		}
		for(int j=1; j<=cnt; ++j) {
			if(prime[j] > v[i] || prime[j] > n/i)
				break;
			v[i*prime[j]] = prime[j];
		}
	}
}

int main() {
	scanf("%d%d", &n, &q);
	is_prime();
	while(q--) {
		int x;
		scanf("%d", &x);
		printf("%d\n", prime[x]);
	}
	return 0;
}

区间筛法

using ll = long long;

bool isprime[maxn], primepart[maxn];

void func(ll l, ll r) {
	for (ll i = 0; i * i <= r; ++i) 
		primepart[i] = 1;
	primepart[1] = 0;
	for (int i = 0; i <= r - l; ++i)
		isprime[i] = 1;
	for (ll i = 2; i * i <= r; ++i) {
		if (primepart[i]) {
			for (ll j = i * i; j * j <= r; j += i)
				primepart[j] = 0;
			for (ll j = max(2ll, (l + i - 1) / i) * i; j <= r; j += i)
				isprime[j - l] = 0;
		}
	}
	int ans = 0;
	for (ll i = l; i <= r; ++i)
		if (isprime[i - l] && i != 1)
			ans++;
	printf("%d\n", ans);
	return;
}

相关题目

  1. 素数密度

质因子分解

由唯一分解定理得。

void divide(int n) {
	m = 0;
	int  t = sqrt(n);
	for(int i=2; i<=t; ++i) {
		if(n % i == 0) {  // 此处能整除n的i一定是质数
			p[++m] = i;	c[m] = 0;
			while(n % i == 0) {
				n /= i;	c[m]++;
			} 
		}
	}
	if(n > 1) {  // 原始的n是质数或者原始的n中最大的质因子大于 sqrt(n)
		p[++m] = n;	c[m] = 1; 
	}
}

约数

定义

若 $n \in $ \(\Zeta\),$d \in $ $ \Zeta $, \(n\) \(\%\) \(d\) \(=\) \(0\),则称 \(d\) 是 \(n\) 的约数,\(n\) 是 \(d\) 的倍数,记作 $ d \mid n $。

算数基本定理

引理

设 \(p\) 是素数,\(p | a_1a_2\),那么 \(p | a_1\) 和 \(p|a_2\) 至少有一个成立。

唯一分解定理

设有 \(a \in \Nu^*\),那么其一定可以表示为若干个素数的乘积。

标准素因数分解式

设有 \(a \in \Nu^*\),必有:

\(a=p_1^{c_1}p_2^{c_2}...p_m^{c_m}, p_1 < p_2 <...< p_m\)

称为正整数 \(a\) 的标准素因数分解式。

算数基本定理与算数基本引理,两个定理等价。

算数基本定理的推论

在算数基本定理中,若 \(n \in \Nu^*\) 被唯一分解为 \(n = p_1^{c_1}p_2^{c_2}...p_m^{c_m}\),其中 \(c_i \in \Nu^*\),\(p_i\) 都是质数,且满足 \(p_1 < p_2 < ...<p_m\),则 \(n\) 的正约数集合可写作:

{\(p_1^{b_1}p_2^{b_2}...p_m^{b_m}\)} ,\(0 \leq b_i \leq c_i\)

\(n\) 的正约数个数为:

\(\prod\limits^{m}_{i=1}\big( \sum\limits^{c_i}_{j=0}(p_i)^j \big)\)

求\(N\) 的正约数集合——试除法

若 \(d \geq \sqrt{N}\) 是 \(N\) 的约数,则 $ d \mid N$ 也是 \(N\) 的约数。也就是说,除完全平方数外,约数总是成对出现的。

据此可得:

gugu.

时间复杂度为 \(\Omicron(\sqrt{N})\)。

试除法的推论

对于一个 \(n \in \Zeta\),其约数个数的上界为 \(2 \sqrt{n}\)。

求 \(1 \sim N\) 每个数的正约数集合——倍数法

gugu.

时间复杂度为 \(\Omicron(N +N/2+N/3+...+N/N)=\Omicron(N\log{N})\)。

倍数法的推论

\(1 \sim N\) 每个数的约数个数总和大约为 \(N\log{N}\)。

例题

  1. [POI2001] [HAOI2007] 反素数

最大公约数

定义

若自然数 \(d\) 同时是自然数 \(a\) 和 \(b\) 的约数,则称 \(d\) 是 \(a\) 和 \(b\) 的公约数。

在所有 \(a\) 和 \(b\) 的公约数中最大的一个数称为 \(a\) 和 \(b\) 的最大公约数。记作 \(\gcd(a, b)\)。

若自然数 \(d\) 同时是自然数 \(a\) 和 \(b\) 的倍数,则称 \(d\) 是 \(a\) 和 \(b\) 的公倍数。

在所有 \(a\) 和 \(b\) 的公倍数中最大的一个数称为 \(a\) 和 \(b\) 的最大公倍数。记作 \(\text{lcm}(a, b)\)。

同理即可定义多个数的最大公约数与最大公倍数。

定理

\(\forall a,b \in \Nu, \gcd(a,b)*\text{lcm}(a,b)=a*b\)。

求 \(\gcd\) 代码实现

int gcd(int a, int b) {
	return b ? gcd(b, a%b) : a;
}

例题

  1. gcd与lcm

  2. Neko does Maths

数论分块

引入

\(f(n)=\sum\limits^{n}_{i=1} \lfloor \frac{n}{i} \rfloor\),给定一个 \(n\) ,求 \(f(n)\) 的值。

需要整除分块的知识。

在给定一个 \(n\) 的前提下,可以发现 \(\lfloor \frac{n}{i} \rfloor\) 的取值在连续一段区间内相同,故可以分为若干块分别进行计算。这就是整除分块的核心思想。

分块数量(时间复杂度分析)

给定一个 \(n\) ,设有集合 \(A = \{x | x = \lfloor \frac{n}{i} \rfloor,1 \leq i \leq n,i \in \Zeta \}\),\(card(A) \leq 2\sqrt{n}\)。

标签:prime,约数,数论,合数,基础,sqrt,int,素数
From: https://www.cnblogs.com/foreverlcrun0817/p/18262381

相关文章

  • 深入解析Redis:从基础到高可用性
    引言在现代应用程序中,数据的高性能、高可用性和一致性至关重要。Redis作为一种开源的内存数据结构存储,不仅提供了极快的读写速度,还支持多种数据结构和高可用性机制。本文将深入探讨Redis的基础知识、关键特性、常见应用场景以及其高可用性机制——主从复制和哨兵。Redis简介......
  • 程序猿大战Python——面向对象——继承基础
    定义类的几种语法==目标:==了解定义类的标准语法。我们知道,可以使用class关键字定义类。在类的使用中,定义方式有三种:(1)【类名】(2)【类名()】(3)【类名(object)】说明:区别在于类名后面是否加其他内容。方式1语法:class类名:代码...方式2语法:class类名(......
  • c#基础
    代码Console.WriteLine(""); Console.ReadKey();//注释ctrl+k-------ctrl+c 注释选中的,ctrl+k-------ctrl+u取消注释/*多行注释*////代码总结 ......
  • Python连接Etcd集群基础教程
    1、背景介绍最近接手了一个项目,项目是使用Python开发的,其中使用到了Etcd,但是项目之前开发的方式,只能够支持单节点连接Etcd,不能够在Etcd节点发生故障时,自动转移。因此需要实现基于现有etcdsdk开发一个能够实现故障转移的功能,或者更换etcdsdk来实现故障转移等功能。先来看看项......
  • 阶段一:Java基础进阶期末题型
    目录前言第一题第二题第三题第四题第五题第六题前言java基础进阶结课期末题第一题需求某小型商城系统的订单信息在素材下的orders.xml文件中,现在要求把xm!中的订单信息,封装成一个一个的订单对象,将订单对象保存到ArrayList集合中。具体功能点要求1)定义订单类......
  • java基础知识面试准备 第三天
    &和&&的区别        &和&&都是Java中的逻辑运算符,用于判断两个布尔表达式的逻辑关系(&和&&的优先级不同,&&的优先级比&高),它们的区别如下:1.&是逻辑与运算符,它的两个操作数都会被求值,只有当两个操作数都为true时,结果才为true;即使第一个操作数为false,第二个操作数也会......
  • 【Linux基础】基础环境配置
    设置APT源进入源文本设置:vim/etc/apt/sources.list配置源:#中科大debhttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontribdeb-srchttp://mirrors.ustc.edu.cn/kalikali-rollingmainnon-freecontrib#阿里云debhttp://mirrors.aliyun.com/kali......
  • 数论
    第一章整除1.1基本性质1.1.1同余与整除定义1.1.:设\(a,b\)为整数,若存在一整数\(c\),使得\(b=ac\),那么我们说\(a\)整除\(b\)并记作\(a|b\)整除的性质1.2.:1)(反射性)对于所有整数\(a\),有\(a|a\).2)(传递性)若有\(a|b\),并且\(b|c\),那么\(a|c\).3)......
  • JavaScript基础部分知识点总结(Part5)
    注册事件(绑定事件)1.注册事件概述给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和方法监听注册方式传统注册方式:利用on开头的事件onclick<buttonοnclick=“alert('hi~')”></button>btn.onclick=function(){}特点:注册事件的唯一性同一个元素同......
  • 基础-几何
    基础-几何1.1.矢量1.1.1.定义以三维空间为例,定义三维空间坐标系x,y,z对应三个单位矢量i,j,k。上述i,j,k另一个数值表示形式为(1,0,0),(0,1,0),(0,0,1)。1.1.2.运算矢量立足于其数值表现形式支持一下运算:1.矢量相加2.矢量相减3.矢量乘以数值4.矢量的点积设矢量a(x1,y1,z1......