数论基础知识(2)【转】

时间:2019-11-13
本文章向大家介绍数论基础知识(2)【转】,主要包括数论基础知识(2)【转】使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

声明

截取oy同学的博客:https://www.luogu.org/blog/ollie906086458/post-1-post
之后再自己整理

六、CRT/EXCRT

1.CRT

转载某大佬(%%%),蒟蒻修改部分

1.定义:

若m[1],m[2],...,m[n] 是两两互质的正整数, \(M= \prod_{i=1}^n{m[i]}\)\(M[i]=M/m[i] ,t[i]\) 是线性同余方程 \(M[i] * t[i] ≡1(\bmod m[i])\)的一个解。对于任意的\(n\)个整数\(a[1], a[2], a[3], ... , a[n]\),则同余方程组为:
\[ \left\{\begin{matrix} x\equiv a_{1}\pmod{m_{1}}\\ x\equiv a_{2}\pmod{m_{2}}\\ ......\\ x\equiv a_{n}\pmod{m_{n}} \end{matrix}\right. \]
有整数解,方程组的解为
\[ x=a_{1}M_{1}t_{1}+a_{2}M_{2}t_{2}+...+a_{n}M_{n}t_{n} \]
并且在%M意义下有唯一解。

2.证明:

因为\(M[i] = M/m[i]\) 是除\(m[i]\) 之外所有模数的倍数,所以 \(∀\) (任意)\(k \neq i\)\(a[i]M[i]t[i]≡0(\bmod m[k])\).又因为 \(a[i]M[i]t[i] ≡a[i] (mod m[i])\),所以代入\(x\)
\[ x=\sum_{i=1}^{n}a_{i}M_{i}t_{i} \]

3.结论:

中国剩余定理给出了模数两两互质的线性同余方程组的一个特殊解。方程组的通解可以表示为\(x+kM(k∈Z)\)。有些题目要求我们求出最小的非负整数解,只需把x对M取模,并让x落在0~M-1的范围内即可。

int intchina(int r)
{
    int Mi,x,y,d,ans=0;
    int M=1;//注意取1
    for(int i=1;i<=r;i++) M*=m[i];
    for(int i=1;i<=r;i++){
        Mi=M/m[i];
        exgcd(Mi,m[i],d,x,y);
        ans=(ans+Mi*x*a[i])%M; //Mi相当于Mi,x—>ti
    }
    return (ans+M)%M;//防负数
}

P1495 曹冲养猪

2.EXCRT

某位神仙说提高不会考,如果考到我认命,如果实在想学可以点击这里

七、线性代数

0.前置

线性代数比较难(矩阵)而且不咋考,所以就马马虎虎地走个过场

1.快速幂

这个大家都会,我就只贴板子了

如果你实在要搞懂原理 戳我

求:
\[ a^{b}\,mod\,p \]
code:

ll quick_pow(ll a, ll b, ll p)//a^b mod p
{
    ll t=1;
    while(b)
    {
        if(b&1) t=t*a%p;
        a=a*a%p;
        b>>=1;
    }
    return t;
}

2.矩阵相关

%%%大佬 可爱即是正义

直接使用传送术(懒得排了,也不是很重要的东西)

可爱即是正义 的博客

3.*高斯消元

某位神级清华sang师说高斯消元noip不会考,不属于提高组,所以不讲,如果感兴趣自己下去查吧。

八、组合数学

前置:这个也是考的比较多的

1.卡特兰数(卡姿兰数)

说明:原博客

1.卡特兰数是啥:

卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

TIP:Cn,hn,fn均表示卡特兰数(在这)

2.卡特兰数的公式

① 递归公式1

\[ f(n)=\sum_{i=0}^{n-1}f(i)*f(n-i-1) \]

如果我们用这个公式显然我们要使用递归算法,那么数据一大就在时空上很麻烦

② 递归公式2

\[ f(n)=\frac{f(n-1)*(4*n-2)}{(n+1)} \]

这个公式应用递推,看上起十分和善

但对大数据呢?

我们注意到大数据的时候 f(n) 会很大,这时候题目一般会让你对某素数取模(当然你可以打高精度

但你在取模过程中难保一个 f(n)%mod=0

那么根据公式下面所有的数都会等于0,于是你就愉快的WA了

③ 组合公式1

\[ f(n)=\frac{C_{2n}^{n}}{(n+1)} \]

卡特兰数可以与组合数联系起来,得到上面的公式

而组合数就是一个杨辉三角,可以递推得到

但我们发现对于大数据你要取模,而对于除法你是没办法用膜的性质的(当然你可以应用逆元),所以造成了麻烦

④ 组合公式2

\[ f(n)=C_{2n}^{n}-C_{2n}^{n-1} \]

与组合数公式1不同这个是两个组合数的减法

减法是可以用膜的性质的,于是你可以愉快的AC了。

3.卡特兰数的应用

①、进出栈问题:

栈是一种先进后出(FILO,First In Last Out)的数据结构.如下图1,2,3,4顺序进栈,那么一种可能的进出栈顺序是:1In→2In→2Out→3In→4In→4Out→3Out→1Out, 于是出栈序列为1,3,4,2。

那么一个足够大的栈的进栈序列为1,2,3,⋯,n时有多少个不同的出栈序列?

例题

我们可以这样想,假设 x 是最后一个出栈的数。

由于x是最后一个出栈的,所以可以将已经出栈的数分成两部分

1.比 x 小

2.比 x 大

比x小的数有x-1个,所以这些数的全部出栈方案数为f[x-1]

比x大的数有n-x个,所以这些数的全部出栈方案数为f[n-x]

所以一共有 \(f[x-1]*f[n-x]\) 种方案。显而易见,\(x\) 取不同值时,产生的出栈序列是相互独立的,所以结果可以累加。\(x\)的取值范围为 \(1\) 至 $ n$,所以结果就为

\(f[n] = f[0] * f[n-1] + f[1] * f[n-2] + ... + f[n-1] * f[0]\)

②. 二叉树构成问题

有n个结点,问总共能构成几种不同的二叉树?

(1)先考虑只有一个节点的情形,设此时的形态有 \(f[1]\) 种,那么很明显 \(f[1]=1\)

(2)如果有两个节点呢?我们很自然想到,应该在 \(f[1]\) 的基础上考虑递推关系。 那么,如果固定一个节点后,左右子树的分布情况为\(1=1+0=0+1\),故有\(f[2] = f[1] + f[1]\)

(3)如果有三个节点,我们需要考虑固定两个节点的情况么?(当然不,因为当节点数量大于等于\(2\)时,无论你如何固定,其形态必然有多种 我们考虑固定一个节点,即根节点)。好的,按照这个思路,还剩2个节点,那么左右子树的分布情况为\(2=2+0=1+1=0+2\)。 所以有\(3\)个节点时,递归形式为 \(f[3]=f[2]+f[1]*f[1]+f[2]\)。(注意这里的乘法,因为左右子树一起组成整棵树,根据排列组合里面的乘法原理即可得出)

(4)那么有n个节点呢?我们固定一个节点,那么左右子树的分布情况为
\(n-1=n-1 + 0 = n-2 + 1 = … = 1 + n-2 = 0 + n-1\)。此时递归表达式为\(f[n] = f[n-1] + f[n-2]f[1] + f[n-3]f[2] + … + f[1]f[n-2] + f[n-1]\)

即给定\(N\)个结点,能构成\(h(N)\)种不同的二叉树。\(h(N)\)为卡特兰数的第\(N\)项。(二叉树性质)

③、凸多边形的三角形划分

一个凸的\(n\)边形,用直线连接他的两个顶点使之分成多个三角形,每条直线不能相交,问一共有多少种划分方案。

这也是非常经典的一道题。我们可以这样来看,选择一个基边,显然这是多边形划分完之后某个三角形的一条边。图中我们假设基边是\(p1-pn\),我们就可以用\(p1,pn\)和另外一个点假设为\(pi\)做一个三角形,并将多边形分成三部分,除了中间的三角形之外,一边是\(i\)边形,另一边是\(n-i+1\)边形。\(i\)的取值范围是\(2\)\(n-1\)。所以本题的解\(c(n)=c(2)c(n-1)+c(3)c(n-2)+...c(n-1)c(2)\)。令\(t(i)=c(i+2)\)。则\(t(i)=t(0)t(i-1)+t(1)t(i-2)...+t(i-1)t(0)\)。很明显,这就是一个卡特兰数了。

④、求n+1个叶子的满二叉树的个数

不证,知道就行

⑤、路径问题

在n*n的格子中,只在下三角行走,每次横或竖走一格,有多少中走法?

其实向右走相当于进栈,向左走相当于出栈,本质就是n个数出栈次序的问题,所以答案就是卡特兰数。(利用这个模型,我们解决这个卡特兰问题的变形问题,并顺便给进出栈问题的解法一个几何解释)

⑥、划分问题

将一个凸n+2边形区域分成三角形区域的方法数?

证明都差不多啦,自己研究去吧

⑦、握手问题

2n 个人均匀坐在一个圆桌边上,某个时刻所有人同时与另一个人握手,要求手之间不能交叉,求共有多少种握手方法

4、引理

这就不说了,没啥对考试太实用的,如果实在想看就往上翻,去原博客看,考试知道这些就行了

5、code

说了一堆终于到终点了哈

代码来自 xiejinhao (%%%)

①公式1:
#include<cstdio>
#define MAX_N 20//这你自己看要定义多大吧
#define ll long long
using namespace std;
int n;
ll f[MAX_N];
int main()
{
    f[0]=f[1]=1;
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        for(int j=0;j<i;j++)
        {
            f[i]+=f[j]*f[i-j-1];
        }
    }
    printf("%lld",f[n]);
    return 0;
}

②公式2:
#include<cstdio>
#define MAX_N 20
#define ll long long
using namespace std;
int n;
ll f[MAX_N];
int main()
{
    f[0]=f[1]=1;
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        f[i]+=f[i-1]*(4*i-2)/(i+1);
    }
    printf("%lld",f[n]);
    return 0;
}

③公式3:
#include<cstdio>
#define MAX_N 20
#define ll long long
using namespace std;
int n;
ll c[MAX_N*2][MAX_N];
int main(){

    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
    {
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;j++)
        {
            c[i][j]=c[i-1][j]+c[i-1][j-1];
        }
    }
    printf("%lld",c[2*n][n]/(n+1));
    return 0;
}

④公式4:
#include<cstdio>
#define MAX_N 20
#define ll long long
using namespace std;
int n;
ll c[MAX_N*2][MAX_N];
int main(){

    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
    {
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;j++)
        {
            c[i][j]=c[i-1][j]+c[i-1][j-1];
        }
    }
    printf("%lld",c[2*n][n]-c[2*n][n-1]);
    return 0;
}

不懂看公式去

卡姿兰数完结

2、排列组合

1、计数原理:

如果 A 地到 B 地有三条路径,B 地到 C 地有两条路径,那么A 到 C 共有 2 * 3 = 6 种方案
如果 A 还有一种直接到 C 的方案,那么就一共有 7 种方案

上面就是加法原理和乘法原理(不知道自行百度好像不知道也无所谓哦

2、排列和组合:

从 n 个元素中取出 m 个元素,排成一排,叫做从 n 个元素中取出 m 个元素的一个排列
\[ A_{n}^{m}=\frac{n!}{(n-m)!} \]
从 n 个元素中取出 m 个元素的所有组合(不管其顺序)的个数,叫做 n 个元素中取出 m 个元素的组合数
\[ C_{n}^{m}=\frac{n!}{m!(n-m)!} \]
这东西太多了,我们讲几个基础的
\[ C_{n}^{m}=C_{n}^{n-m},C_{n}^{0}=C_{n}^{n}=1 \]
可以理解为:将原本的每个组合都反转,把原来没选的选上,原来选了的去掉,这样就变成从n个元素种取出n−m个元素,显然方案数是相等的。
\[ C_{n}^{m}=C_{n-1}^{m}+C_{n-1}^{m-1} \]
可理解为:含特定元素的组合有\(C^{m-1}_{n-1}\),不含特定元素的排列为\(C^{m}_{n-1}\)

组合数求和公式:
\[ C_{n}^{0}+C_{n}^{1}+C_{n}^{2}+...+C_{n}^{n}=2^{n} \]
自己记去

3、二项式定理

可以将x+y的任意次幂展开成和的形式
\[ (x+y)^{n}=\binom{n}{0}x^{n}y^{0}+\binom{n}{1}x^{n-1}y^{1}+\binom{n}{2}x^{n-2}y^{2}+...+\binom{n}{n-1}x^{1}y^{n-1}+\binom{n}{n}x^{0}y^{n} \]
其中每个\(\binom{n}{k}\)为一个称作二项式系数的特定正整数,其等于\(\frac{n!}{k!(n-k)!}\)。这个公式也称二项式公式或二项恒等式。使用求和符号,可以把它写作
\[ (x+y)^{n}=\sum_{k=0}^{n}\binom{n}{k}x^{n-k}y^{k}=\sum_{k=0}^{n}\binom{n}{k}x^{k}y^{n-k} \]
P1313 计算系数

4、杨辉三角

来自古人的神秘力量

大佬博客的搬运工——ollie

杨辉三角可以帮助你更好地理解和记忆组合数的性质:

  1. \(n\)行的\(m\)个数可表示为 \(C^{m-1}_{n-1}\),即为从\(n-1\)个不同元素中取\(m-1\)个元素的组合数。
  2. \(n\)行的数字有\(n\)项。
  3. 每行数字左右对称(第\(n\)行的第\(m\)个数和第\(n-m+1\)个数相等,\(C_{n}^{m}=C_{n}^{n-m}\),由\(1\)开始逐渐变大。
  4. 每个数等于它上方两数之和(第\(n+1\)行的第\(i\)个数等于第\(n\)行的第\(i-1\)个数和第\(i\)个数之和,即\(C_{n+1}^{i}=C^{i}_{n}+C_{n}^{i-1}\)
  5. \((a+b)^{n}\)的展开式中的各项系数依次对应杨辉三角的第\(n+1\)行中的每一项(二项式定理)。

code:

c[1][1] = 1;
    for(int i = 2; i <= n; i++)
    for(int j = 1; j <= i; j++)
    {
        c[i][j] = c[i-1][j] + c[i-1][j-1];
    }

P1118 数字三角形

P2822 组合数问题

九、数学期望

所有的权值乘以它对应的概率

通俗一点就是设\(X[i]\)\(i\)的权值,\(P[i]\)\(i\)对应出现的概率,期望值为\(f\),有:
\[ f=\sum_{i=1}^{n}X[i]* P[i] \]

完结撒花

还有部分内容未补上,后期补充上去

原文地址:https://www.cnblogs.com/tyner/p/11847237.html