zoukankan      html  css  js  c++  java
  • 数论基础知识(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] ]

    完结撒花

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

  • 相关阅读:
    2016"百度之星"
    codeforces 55 div2 C.Title 模拟
    codeforces 98 div2 C.History 水题
    codeforces 97 div2 C.Replacement 水题
    codeforces 200 div2 C. Rational Resistance 思路题
    bzoj 2226 LCMSum 欧拉函数
    hdu 1163 九余数定理
    51nod 1225 余数的和 数学
    bzoj 2818 gcd 线性欧拉函数
    Codeforces Round #332 (Div. 2)D. Spongebob and Squares 数学
  • 原文地址:https://www.cnblogs.com/tyner/p/11847237.html
Copyright © 2011-2022 走看看