数论基础知识(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(mod m[i]))的一个解。对于任意的(n)个整数(a[1], a[2], a[3], ... , a[n]),则同余方程组为:

[left{egin{matrix} xequiv a_{1}pmod{m_{1}}\ xequiv a_{2}pmod{m_{2}}\ ......\ xequiv a_{n}pmod{m_{n}} end{matrix} ight. ]

有整数解,方程组的解为

[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 eq i)(a[i]M[i]t[i]≡0(mod 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个叶子的满二叉树的个数

QQ20151105-6

不证,知道就行

⑤、路径问题

在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}=inom{n}{0}x^{n}y^{0}+inom{n}{1}x^{n-1}y^{1}+inom{n}{2}x^{n-2}y^{2}+...+inom{n}{n-1}x^{1}y^{n-1}+inom{n}{n}x^{0}y^{n} ]

其中每个(inom{n}{k})为一个称作二项式系数的特定正整数,其等于(frac{n!}{k!(n-k)!})。这个公式也称二项式公式或二项恒等式。使用求和符号,可以把它写作

[(x+y)^{n}=sum_{k=0}^{n}inom{n}{k}x^{n-k}y^{k}=sum_{k=0}^{n}inom{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