夏令营讲课内容整理 Day 6 Part 2.

Day 6的第二部分,数论

数论是纯粹数学的分支之一,主要研究整数的性质

1.一些符号:

a mod b 代表a除以b得到的余数

a|b a是b的约数

floor(x) 代表x的下取整,即小于等于x的最大整数,也可以认为是直接舍去小数部分

(这个应该是一个符号,但我不知道怎么打出来。。下面那个ceil也是)

ceil(x) 代表x的上取整,即大于等于x的最小整数,也可以认为是直接舍去小数部分再+1.

gcd(a,b) 表示a与b的最大公约数

lcm(a,b) 表示a与b的最小公倍数

累加符号∑ 累乘符号∏

logab代表以a为底的b的对数,ln表示以e为底的对数,lg代表以10为底的对数

2.质数

也称素数,是质因子只有1和它本身的数。

与质数相对的是合数,合数在因数拆分时可以拆分成至少两对其他数的乘积。

特殊规定,1既不是质数也不是合数。

可以证明,素数是无限多个的,证明从略。

3.唯一分解定理

算术基本定理之一。

定理是这样描述的:对于每一个大于1的自然数都可以写成质数的积,而这些因子按照大小排列后,只有一种结果(写法只有一种)。

我并不会证。。。我太弱了

这个定理是分解质因数的基础。它告诉我们可以用质数乘积的形式处理一些大数字,处理一类和约数有关的问题。

显然,一个数n最多有一个大于√n的质因子。

4.筛法

用来快速求一个数是不是质数的算法

通常有两种筛法:埃氏筛和欧拉筛

4.1埃氏筛法

核心思想:从2到n枚举,当找到一个质数时,枚举它的所有倍数,这些倍数绝对不可能是质数。

int cnt;
int prime[maxn];
bool vis[maxn];
void Eratosthenes(int n){
    for (int i=2;i<=n;i++)
        if (!vis[i]){
            prime[++cnt] = i;
            for (int j = i*2;j<=n;j+=i)
                vis[j] = 1;
        }
}

时间复杂度是O(nloglogn),证明从略。

4.2欧拉筛法

核心思想是通过让每一个数只会被它最小的质因子筛到,从而每个数只会被筛一次,时间复杂度O(n)。

对于任意一个合数,我们可以拆成最小质因子*某数i的形式,我们枚举这个数i,然后再枚举出所有筛的质数。

当我们枚举的质数可以整除i时,如果再往大里枚举,枚举的质数就不可能是最小质数了。这时就可以终止循环,继续枚举下一个i。

int cnt;
int prime[maxn];
bool vis[maxn];
void Eular(int n){
    for (int i=2;i<=n;i++){
        if (!vis[i])
            prime[++cnt] = i;
        for (int j=1;j<=cnt && prime[j]*i<=n;++j){
            vis[prime[j]*i] = 1;
            if (i % prime[j] == 0)
                break;
        }
    }
}

5.取模

我想您应该早已熟知余数的定义。

a % b(就是a mod b)得到的结果是a除以b得到的余数。

性质:a %b = floor(a/b)

一些题目要求对答案取模,如果这个答案是负的,应该加上模数而不是除。

取模的性质:

(a±b) % p = ((a % p) ± b) % p

(a*b) %p=(a % p) * (b % p)

6.最大公约数

辗转相除。

int gcd(int a, int b){
  if (!b)
    return a;
  return gcd(b, a % b);
}
 

7.同余

这里引入一个新符号,a≡b(mod n)表示a与b在模n意义下的余数相同,称为a与b同余。

同余的性质:

1.反身性 a≡a (mod m)

2.对称性 若a≡b(mod m),则b≡a (mod m)

3.传递性 若a≡b (mod m),b≡c (mod m),则a≡c (mod m)

4.同余式相加 若a≡b (mod m),c≡d(mod m),则a+c≡b+d (mod m)(或换成-)

5.同余式相乘 若a≡b (mod m),c≡d(mod m),则ac≡bd (mod m)

7.1逆元

如果 ax≡1(mod n),那么x为a关于模n意义下的逆元。

逆元一般用inv简称。

当gcd(a,n) = 1时x为一唯一值,否则不存在,证明从略。

其实可以这么想,x为模n意义下的倒数,也就是1/a,我们可以类比实数意义下的倒数在模n意义下a乘以b的逆元,相当于模n意义下的a/b。

求逆元的方法,接下来讲。

8.扩展欧几里得算法

(借鉴了gty哥哥课件的思路)

简称扩欧,exgcd。

用来求解形似ax+by = gcd(a,b)一类方程的解。

这里的x和y不一定是正整数,有可能是负数或0.

比如说我举个例子,求一直线ax+by+c = 0上有多少个整数点(x,y)满足x∈[x1,x2],y∈[y1,y2]

边界情况:

当b=0时,gcd(a,b)=a,x=1,y=0

假设 ax1 + by1= gcd(a,b),bx2 + (a % b)y2= gcd(b,a % b)

由gcd的意义,知gcd(a,b) = gcd(b,a % b),那么有ax1 + by1 = bx2+ (a % b)y2;

也就是说ax1 + by1 = bx2 + (a - [a / b] * b)y2 = ay2 + bx2 - [a / b] * by2;

也就是说ax1 + by1 == ay2+ b(x2 - [a / b] *y2);

那么,x1 = y2; y1 = x2 - [a / b] * y2;

这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2。我们可以通过不断递归调用求解。

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

我们这样只能得出一组解,其他解呢?如果我们现在有解(x1,y1),任取另外一组解(x2,y2),则有ax1 + by1 = ax2 + by2 = gcd(a, b),变形可以得到a(x1 – x2) = b(y2 – y1),两边同时除以gcd(a, b),得到a’(x1 – x2) = b’(y2 – y1),因为(a’,b’)=1,所以(x1-x2)一定是b’的倍数,取x1-x2=kb’,得y2-y1=ka’。

所以我们有以下结论:

对方程ax+by+c=0,一组整数解为(x0,y0),则它的任意整数解可以写成(x0+kb’,y0-ka’),其中a’=a/gcd(a, b),b’=b/gcd(a, b)

关于ax+by=c有没有解,我们有这么一个结论:

对于方程ax+by=c(a,b,c均为整数),如果c为gcd(a,b)的倍数,则方程有整数解,反之无整数解。因为a和b都是gcd(a,b)的倍数,所以ax+by一定也是gcd(a,b)的倍数,如果c不是gcd(a,b)的倍数,一定无解。

那刚才那道题怎么做呢?

方程变形为ax+by = -c,看一下-c是不是gcd(a,b)的倍数,然后用exgcd求一下ax+by = gcd(a,b)的解,记为(x0,y0)。

等式两边同乘(-c)/gcd(a,b),就有ax0‘+by0‘ = -c

用刚才的结论,求出使x = x0 + kb‘落在区间[x1,x2]内的k的范围和使y = y0-ka‘落在区间[y1,y2]内的k的范围,取交集就是答案。

9.费马小定理

如果p是质数,并且gcd(a,p) = 1,那么 a^(p-1) ≡ 1 (mod p)

由这个式子我们可以知道,a关于p的逆元就是a^(p-2) % p,用快速幂就好,证明从略。

10.快速幂

快速幂用了一个倍增的思想,我把它放在Part 3.

11.排列组合

11.1排列

排列数指的是从n个数中任取m个元素排成有顺序的一列,这一列称为一个排列,所有排列总数称为排列数。

生成排列数:DFS 或 next_permutation

从n个元素里取m个成为排列记为A(n,m) (原谅打不出来)

A(n,m) = n * (n-1) * (n-2) * (n-3) * ... * (n-m+1) = n!/m!(n-m)!

11.2组合

组合数指的是从n个数中任取m个 元素设为一组,叫做一个组合,这样所有的组合的数量就是组合数。

可以发现,排列要求元素带有顺序,而组合则不考虑顺序。

公式是C(n,m) = n * (n-1) * (n-2) * (n-3) * ... * (n-m+1)/m! = n!/m!(n-m)!

组合的性质:

C(n,m) = C(n-1,m-1) + C(n-1,m)

C(n,m) = C(n,n-m)

C(n,m) = C(n,m-1)*(n-m+1)/m (m>0)

由性质3可递推某一n确定下的组合数

其实排列组合这一块有很多内容,然而。。。

我觉得我讲得再多也没高中数学选修2-3讲得明白。。。。

所以,如果有没提到的地方,请参见高中数学选修2-3。。

时间: 2024-10-24 20:36:15

夏令营讲课内容整理 Day 6 Part 2.的相关文章

夏令营讲课内容整理Day 0.

今年没有发纸质讲义是最气的.还好我留了点课件. 第一次用这个估计也不怎么会用,但尝试一下新事物总是好的. 前四天gty哥哥讲的内容和去年差不多,后三天zhn大佬讲的内容有点难,努力去理解吧. 毕竟知识还是需要消化的. 这里我只整理知识点,每天上午评测的题目我会单独处理. 嗯大概就是这样了. 写完后我就会考虑发到博客园里.

夏令营讲课内容整理 Day 3.

本日主要内容是树与图. 1.树 树的性质 树的遍历 树的LCA 树上前缀和 树的基本性质: 对于一棵有n个节点的树,必定有n-1条边.任意两个点之间的路径是唯一确定的. 回到题目上,如果题目读入的是树上所有的边,则我们应该想到: 每个点的父亲是谁 每个点的深度 每个点距离根节点的距离 其他的附加信息(例如:子树和,子树最大值..) 遍历整个树的代码如下: 1 void dfs(int now) 2 { 3 deep[now]=deep[fa[now]]+1; 4 sum[now]=value[n

夏令营讲课内容整理 Day 5.

DP专场.. 动态规划是运筹学的一个分支, 求解决策过程最优化的数学方法. 我们一般把动态规划简称为DP(Dynamic Programming) 1.动态规划的背包问题 有一个容量为m的背包,有n个物品,每一个物品i的重量为w[i],价值为v[i]. 要求选择一些物品放入背包中,每种物品只能最多使用一次,使得在不超重的情况下让背包中所有物品价值总和最大. 正常向解法:设状态数组f[i][j]为把前i个物品放入一个容量为j的背包中所能获得的最大价值(以下同设),则状态转移方程为: f[i][j]

夏令营讲课内容整理 Day 4.

本日主要内容就是搜索(打暴力 搜索可以说是OIer必会的算法,同时也是OI系列赛事常考的算法之一. 有很多的题目都可以通过暴力搜索拿到部分分,而在暴力搜索的基础上再加一些剪枝优化, 就有可能会拿到更多的分数. 有句话说的好嘛,骗分过样例,暴力出奇迹. 真的可以出奇迹的,只要你用得好. 1.搜索的概念 在一个给定的空间内,运用一定的查找(遍历)方式,直到找到目标解(状态)的过程,我们称之为搜索. 搜素是尝试性的,搜索是无脑的,搜索是朴素的,搜索在很多时候是显然的,搜索应该总是暴力的.但搜索也是很常

夏令营讲课内容整理Day 1.

主要内容是栈和队列. 1.  栈 运算受到限制的线性表.只允许从一端进行插入和删除等操作.这一端便是栈顶,另一端便是栈底. 其实可以把栈想象层任何有底无盖的柱状的容器...毕竟栈满足后进先出的特性.计算机当中调用函数时,中间结果便会保存到「系统栈」中.递归过程也需要栈的协助 . 实现:STL or 手写(请参照一本通 or 课件) 一般操作:判断栈空/满.入栈.出栈,判断栈的大小(请参照一本通 or 课件) 1.1 单调栈 顾名思义,保证内部元素单调(单增或单减)的栈.我们只要在插入新元素的时候

夏令营讲课内容整理 Day 6 Part 1.

Day6讲了三个大部分的内容. 1.STL 2.初等数论 3.倍增 Part1主要与STL有关. 1.概述 STL的英文全名叫Standard Template Library,翻译成中文就叫标准模板库. 它有点类似于一个大型的工具箱,里面包含许多实用工具,可以拿过来直接用而大部分情况下无需去深入探究其内部原理. 不知道从什么时候开始,CCF不再限制选手使用STL,所以在OI赛事中STL被广泛应用. 它分为六个大部分: 1)容器 containers 2)迭代器 iterators 3)空间配置

夏令营讲课内容整理 Day 2.

本日主要内容是并查集和堆. 并查集 并查集是一种树型的数据结构,通常用来处理不同集合间的元素之间的合并与查找问题.一个并查集支持三个基本功能:合并.查找和判断.举一个通俗的例子,我和lhz认识,lhz和hzc认识,那么也就可以断定我和hzc认识. 依照并查集的思想,我们把所有要待处理的元素a1,a2,a3....an这n个元素都看作是一个单独的集合,初始状态每个集合都只有一个元素.我们就可以把并查集的合并操作理解为集合之间的取并集操作. 作为一个树形结构,在一个由许多这样的集合构成的森林中,每个

Google C++ 风格指南内容整理

之前一直没有全面的看过Google C++风格指南,现在很多公司进行C++开发都要求按照Google C++风格.在这个网站 http://zh-google-styleguide.readthedocs.org/en/latest/contents/  有人已经把其翻译成中文.为了便于以后查看,下面的内容完全是来自于这个网站,只是把多个网页的内容整理放在了一起. 1.      头文件: 通常每一个.cc文件都有一个对应的.h文件.也有一些常见例外,如单元测试代码和只包含main()函数的.c

网页格式化排版代码,专用信息采集后的内容整理

public static string ClearHtml(string content) { Regex regex = new Regex(""); //首先把p标签的属性去掉,只留<p> regex = new Regex(@"<p.*?>", RegexOptions.IgnoreCase | RegexOptions.Singleline); content = regex.Replace(content, "<p