数论 \(1\)

\(1.\) 质数

定义就不说了吧。

性质 \(\&\) 定理

  • 质数 \(p\) 有且仅有两个质因子 \(1\) 和 \(p\) 。

  • 质数有无穷个。

  • \([1,\, n]\) 中的质数个数约为 \(\dfrac{n}{\ln n}\) (此结论可用来大致估算某些数论题的数据范围)。

  • 任何一个大于 \(1\) 的整数 \(N\) 都可以分解成 \(\large N = \prod\limits_{i = 1}^k p_i^{\alpha_i} \ (\forall i ,\, p_i\in \mathbb P ,\, a_i \in \mathbb{N^*})\) 的形式,如果不计各个质因数的顺序,那么这种分解是惟一的

筛质数——线性筛法

线性筛法,顾名思义,可以筛出 \([1,\, n]\) 内的所有质数,时间复杂度为 \(\mathcal O (n)\) 。

int primes[N], cnt;
// primes存放所有的质数,cnt是质数的数量
int st[N];
// st[i]记录每个数是否是质数 void init(int n){
for(int i = 2; i <= n; ++i){
if(!st[i]) primes[cnt++] = i;
for(int j = 0; primes[j] * i <= n && j < cnt; ++j){
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
}
}
}

\(2.\) 约数

定义还是就不说了吧。~~

性质 \(\&\) 定理

  • 对于任何一个大于 \(1\) 的整数 \(N\),如果将其分解质因数为 \(\large N = \prod\limits_{i = 1}^k p_i^{\alpha_i} \ (\forall i ,\, p_i\in \mathbb P ,\, a_i \in \mathbb{N^*})\) 的形式,那么 \(N\) 的正约数个数为 \(\large \prod\limits_{i = 1}^k (\alpha_i + 1)\) , \(N\) 的所有正约数的和为 \(\large \prod\limits_{i = 1}^k \left(\sum\limits_{j = 0}^{\alpha_i} p_i^j\right)\) 。
  • \(2^{31}\) 内约数个数最多的数有 \(1600\) 个约数;\(2^{63}\) 内约数个数最多的数有 \(138240\) 个约数。

求约数个数

对于要重复计算多次的,先筛出质数,代码效率会有所提高。

int get_divisors(int x){
int res = 1, s;
for(int i = 0; primes[i] < x / primes[i]; ++i){
int p = primes[i];
s = 0;
while(x % p == 0){
++s;
x /= p;
}
res *= s + 1;
}
if(x > 1) res *= 2;
// 这里一定记得判断是否有还没除尽的质因子 return res;
}

\(3.\) 欧拉函数 \(\varphi\)

定义

\(\varphi(n)\) 表示小于等于 \(n\) 的正整数中与 \(n\) 互质的数的个数。

计算方法

对于任何一个大于 \(1\) 的整数 \(N\),如果将其分解质因数为 \(N = {\large \prod}\limits_{i = 1}^k \, p_i^{\alpha_i} \ (\forall i ,\, p_i\in \mathbb P ,\, a_i \in \mathbb{N^*})\) 的形式,那么:

\[\varphi(N) = N \prod\limits_{i = 1}^k \left( 1 - \cfrac 1{p_i} \right)
\]

特别地,\(\varphi(1) = 1\) 。

性质 \(\&\) 定理

有一堆,慢慢看吧,理性了解,证明的话有兴趣可以自己去搜索。

  • 对于质数 \(p\),\(\varphi(p) = p - 1\) 。
  • 若 \(p\) 为质数,\(n = p^k \ (k \in \mathbb{N^*})\) ,那么 \(\varphi(n) = p^k - p^{k - 1}\) 。
  • 若 \(a \mid n\),那么 \(\varphi(an) = a \varphi(n)\) 。
  • 若 \((n, m) = 1\) ,那么 \(\varphi(n) \varphi(m) = \varphi(nm)\) 。
  • 当 \(n > 2\) 时,\(\varphi(n)\) 为偶数。
  • 若 \(n\) 为大于 \(1\) 的正整数,那么在小于等于 \(n\) 的正整数中,与 \(n\) 互质的数之和为 \(\dfrac{n \varphi(n)}{2}\) 。
  • $ n = {\large \sum}\limits_{d \mid n} , \varphi(d)$ 。

\(4.\) 线性筛法求欧拉函数 \(\varphi\)

利用线性筛法以及欧拉函数的性质,可以筛出 \([1,\, n]\) 内的所有质数,顺便求出 \([1,\, n]\) 内的所有整数的欧拉函数,时间复杂度为 \(\mathcal O (n)\) 。

int primes[N], cnt;
int phi[N];
bool st[N]; void init(int n){
phi[1] = 1;
for(int i = 2; i <= n; ++i){
if(!st[i]){
primes[cnt++] = i;
phi[i] = i - 1;
// 前面的性质1
}
for(int j = 0; primes[j] * i <= n && j < cnt; ++j){
st[primes[j] * i] = 1;
if(i % primes[j] == 0){
phi[i * primes[j]] = phi[i] * primes[j];
// 性质3
break;
}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
// 这个可以直接由计算方法推出来
}
}
}

\(5.\) 欧拉定理

\(\text{Content}\)

若 \(a, n \in \mathbb{N^*}\) ,且 \((a, n) = 1\) ,则有:

\[\large a^{\varphi(n)} \equiv 1 \pmod n
\]

特别地,当 \(n \in \mathbb P\) 时,这就成了费马小定理

若 \(p \in \mathbb P\) ,且 \(p \nmid a\) 则有:

\[\large a^{p - 1} \equiv 1 \pmod p
\]

\(6.\) 综合应用

\(\texttt{E}\color{red}{\texttt{g} 1}\)

给定整数 \(N\),将 \(N!\) 分解质因数,按照算术基本定理的形式输出分解结果中的 \(p_i\) 和 \(c_i\) 。

按照 \(p_i\) 由小到大的顺序输出。

  • \(3 \le N \le 10^6\)

首先 \(N \le 10^6\) ,所以 \(N!\) 会很大,直接分解肯定不行,考虑从 \(N!\) 的特殊性质入手。

\(N! = 1 \times 2 \times \cdots \times N\)

那么对于一个质数 \(p\) ,\(1 \sim N\) 中的 \(p,2p,\dots,kp\) ( \(p\) 的倍数)肯定含有质因子 \(p\) ,可以很容易得出个数为 \(\left\lfloor \dfrac Np \right\rfloor\) 。

但这还会漏掉一些,如果一个数中含有 \(2\) 个因子 \(p\) ,会被漏算一次,因此还需要加上 \(1 \sim N\) 中的 \(p^2,2p^2,\dots,kp^2\) ,有 \(\left\lfloor \dfrac N{p^2} \right\rfloor\) 个。

以此类推,\(N!\) 中某个质因子 \(p\) 的次数为

\[\sum\limits_{k = 1}^{\left\lfloor \log_p n \right\rfloor} \left\lfloor \dfrac N{p^k} \right\rfloor
\]

那么接下来枚举所有小于等于 \(N\) 的质数,再分别求和就好了,时间复杂度 \(\mathcal O(N)\) 左右吧(有点不好分析,反正过肯定是没问题的)。

\(\mathcal{Code}\)

#include <cstdio>

using namespace std;
typedef long long ll; const int N = 1e6 + 10; int n;
int primes[N], cnt;
bool st[N]; void init(int n){
for(int i = 2; i <= n; ++i){
if(!st[i]) primes[cnt++] = i;
for(int j = 0; primes[j] * i <= n && j < cnt; ++j){
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
}
}
} int main(){
scanf("%d", &n);
init(n); for(int i = 0; i < cnt; ++i){
int p = primes[i], s = 0;
int k = n;
while(k){
s += k / p;
k /= p;
}
printf("%d %d\n", p, s);
} return 0;
}

\(\texttt{E}\color{red}{\texttt{g} 2}\) 洛谷P2158 [SDOI2008] 仪仗队

作为体育委员,C 君负责这次运动会仪仗队的训练。仪仗队是由学生组成的 \(n \times n\) 的方阵,为了保证队伍在行进中整齐划一,C 君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。

现在,C 君希望你告诉他队伍整齐时能看到的学生人数。

  • 对于 \(100 \%\) 的数据,\(1 \le n \le 40000\)。

首先进行分析,将仪仗队放在一个平面直角坐标系中,无法看到的学生是因为被在同一条从原点出发的直线上的前面的学生挡住了。

那么可以得到学生能被看到的条件是横纵坐标互质

答案就是:

\[\sum_{i = 1}^{n - 1} \sum_{j = 1}^{n - 1} [\gcd(i,j) = 1] + 2
\]

最后加上的两个是 \((0,1)\) 和 \((1,0)\) 。

上式变一下(配合着图可能更好理解一些):

\[2 \sum_{i = 1}^{n - 1} \sum_{j = 1}^{i} [\gcd(i, j) = 1] + 1
\]

这里我们惊喜的发现,可以用 \(\varphi(i)\) 来表示 \({\Large \sum}\limits_{j = 1}^{i} \, [\gcd(i, j) = 1]\)

于是,最后的柿子就出来咯:

\[{\rm Ans} = 2 \sum_{i = 1}^{n - 1} \varphi(i) + 1
\]

当然,当 \(n = 1\) 时,是没有学生的,也不满足上面的结论,需要特判一下。

代码就很好实现啦,用线性筛求个欧拉函数就可以 \(\color{#52C41A}{\text{AC}}\) 此题,\(\mathcal O(n)\) 根本不虚。

\(\mathcal{Code}\)

#include <iostream>
#include <cstring>
#include <cstdio> using namespace std;
typedef long long ll; const int N = 40010; int T, n, res = 1; // +1跑到这里来了哦
int primes[N], cnt;
int phi[N];
bool st[N]; void init(int n){
phi[1] = 1;
for(int i = 2; i <= n; ++i){
if(!st[i]){
primes[cnt++] = i;
phi[i] = i - 1;
}
for(int j = 0; primes[j] * i <= n && j < cnt; ++j){
st[primes[j] * i] = 1;
if(i % primes[j] == 0){
phi[i * primes[j]] = phi[i] * primes[j];
break;
}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
} int main(){
scanf("%d", &n);
if(n == 1){
puts("0");
return 0;
}
init(n); for(int i = 1; i < n; ++i) res += 2 * phi[i]; printf("%d\n", res);
return 0;
}

蒟蒻很弱,如有错漏还请各位大佬指出

感谢~~~

数学 in OI-数论-1的更多相关文章

  1. 数学概念——J - 数论,质因数分解

    J - 数论,质因数分解 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  2. 数学概念——I - 数论,线性方程

    I - 数论,线性方程 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit  ...

  3. 【数学】NOIP数论内容整理

    NOIP数论内容整理 注:特别感谢sdsy的zxy神仙以及lcez的tsr筮安帮助审稿 一.整除: 对于\(a,b~\in~Z\),若\(\exists~k~\in~Z\),\(s.t.~b~=~k~ ...

  4. OI 数论整理

    1.素数: 质数(prime number)又称素数,有无限个.一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数. 2016 ...

  5. 数学(快速数论变换):SDOI2015 序列统计

    [题目描述] 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列.但是小C有 ...

  6. 模板 - 数学 - 多项式 - 快速数论变换/NTT

    Huffman分治的NTT,常数一般.使用的时候把多项式的系数们放进vector里面,然后调用solve就可以得到它们的乘积.注意这里默认最大长度是1e6,可能需要改变. #include<bi ...

  7. 【BZOJ4173】数学 题解(数论)

    前言:体验到了推式子的快感orz 题目大意:求$\varphi(n)*\varphi(m)*\sum_{n\ mod\ k+m\ mod\ k\geq k} \varphi(k)\ mod\ 9982 ...

  8. 简单数论之整除&质因数分解&唯一分解定理

    [整除] 若a被b整除,即a是b的倍数,那么记作b|a("|"是整除符号),读作"b整除a"或"a能被b整除".b叫做a的约数(或因数),a ...

  9. 一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)

    转自:http://www.math.org.cn/forum.php?mod=viewthread&tid=14819&extra=&page=1 原作者: wcboy 现在 ...

  10. 数学相关【真·NOIP】

    数论相关 上来就不会的gcd相关.见SCB他威胁我去掉了一个后缀的blog好了:https://blog.csdn.net/suncongbo/article/details/82935140(已经过 ...

随机推荐

  1. 详解pyautogui模块

    一.安装 pip install pyautogui 或者 pip install -i  https://pypi.tuna.tsinghua.edu.cn/simple pyautogui 二.全 ...

  2. 如何在CentOS7上搭建自己的GitLab仓库

    序言 各位好啊,我是会编程的蜗牛,作为java开发者,在团队开发中,一般都是需要使用git及git仓库来管理我们的代码的,这非常方便.我以前在小公司的时候,基本都是一个人开发一个项目,所以也没有怎么接 ...

  3. 接入监控视频,为啥还需要对接厂商的SDK呢,不是有onvif这样的标准协议吗?

    不少人问过我这个问题,这真是一个好问题. 我举两个例子,让您仔细品: ① 快速打开视频和极致操控的问题. onvif协议很科班,但厂商的sdk可能会给你一些独特的方法,譬如先make一个I帧,这样第一 ...

  4. 强连通分量与tarjan算法初步运用

    模板题:B3609 [图论与代数结构 701] 强连通分量 题目描述 给定一张 n 个点 m 条边的有向图,求出其所有的强连通分量. 注意,本题可能存在重边和自环. 输入格式 第一行两个正整数 n , ...

  5. mybatis不知道取什么名字的标题

    <!--根据多个id --> <foreach collection="ids" index="index" item="item& ...

  6. 【题解】CF1659E AND-MEX Walk

    题目传送门 位运算 设题目中序列 \(w_1,w_1 \& w_2,w_1 \& w_2 \& w_3,\dots,w_1 \& w_2 \& \dots \& ...

  7. 32bit和64bit系统的区别,运行机制浅析

    32bit:内存的最大寻址空间是2^32=4G,就是说32位系统的处理器最大只支持到4G内存 64bit:内存的最大寻址空间是2^64,大于1亿GB,但是实际上支持不到那么大的内存,大概是2^40+ ...

  8. 实现Swaggera的在线接口调试

    1.访问Swagger的路径是:http://localhost:8080/swagger-ui.html 如果项目正常,则可看到如下界面: 2.点开下面的随意一个方法 如add添加数据的方法,展开: ...

  9. C++初阶(类的访问权限以及封装+this指针+构造函数+析构函数+拷贝构造函数+参数列表+友元+内部类)

    面向过程与面向对象 C语言是面向过程的,关注的是过程(函数),分析出求解问题的步骤,通过函数调用逐步解决问题. C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成. ...

  10. 高精度加法(Java)

    题目描述 高精度加法,相当于 a+b problem,不用考虑负数. 输入格式 分两行输入. a , b ≤ 10^500 输出格式 输出只有一行,代表 a + b  的值. 思路 使用数组进行模拟, ...