#NOIP前數學知識總結

我好菜啊……ios

歐拉函數

歐拉函數φ(n),是小於n且和n互質的正整數(包括1)的個數。ide

性質:

1.對於質數n:函數

$φ(n)=n-1$ui

 

2..對於n=pklua

$φ(n)=(p-1)*p^{k-1}$spa

3.積性函數的性質:3d

對於互質的m,n,有:code

$φ(n*m)=φ(n)*φ(m)$xml

4.歐拉函數的計算式:blog

$φ(n)=n*\Pi (1-\frac{1}{p_i})$

5.求小於n且與n互質的數的和:

$S=n*φ(n)/2$

歐拉定理

對於互質的a,m,有:

$a^{\varphi (m)}\equiv 1(mod\  m)$

能夠看出費馬小定理是歐拉定理的特殊狀況。

歐拉定理能夠用於指數取模,即$x^y\ \equiv x^{y\ mod\ \varphi (p)}\ (mod\ p)$,p爲質數

歐幾里得定理

$gcd(a,b)=gcd(b,a\ mod\ b)$

擴展歐幾里得

已知a,b,求解一組x,y,使他們知足$ax+by=gcd(a,b)$

證實:

ax+by=gcd(a,b);

1. (1) $a = 0$,$ax+by = gcd(a,b) = gcd(0,b) = b$,

此時$x = 0$(此時x的值是任意的),$y = 1$;

    (2)$b = 0$,$ax + by = gcd(a,b) = gcd(a,0) = a$,

此時$x = 1,y = 0$(此時y的值是任意的);

2.a和b都不爲0時

$ax1 + by1 = gcd(a, b)$

由歐幾里德定理:$gcd(a,b) = gcd(b, a\% b)$得

$ax1 + by1 = gcd(a,b) = gcd(b, a\% b)$ 即:

$bx2 + a\% by2 = gcd(b, a\% b) = ax1 + by1$

$a \% b = a - a/b*b$;

$ax1 + by1 = bx2 + (a - a/b*b)y2$;

                $=bx2 + ay2 - a/b*b*y2$;

                $=ay2 + b(x2-a/b*y2)$;

因此:$x1 = y2,y1 = x2 - a/b*y2$

代碼

 

int exGcd(int a,int b,int &d,int &x,int &y)
{
    if(!b) { d=a;x=1;y=0; }
    else { gcd(b,a%b,d,y,x); y-= x*(a/b); }
}
View Code

 

 

 

 求解$ax+by=c$時:

int exgcd(int a,int b,int &x,int &y,int c)
{
    if(!b)
    {
        x=c/a;
        y=0;
        return a;
    }
    int g=exgcd(b,a%b,y,x,c);
    y-=a/b*x;
    return g;
}
View Code

 

 

 

費馬小定理

對於質數p,任意整數a,且a、p互質,有:

$a^p\equiv a(mod\  p)$,即$a^{p-1}\equiv 1(mod\  p)$

乘法逆元

除以一個數再取模等同於乘以這個數的逆元再取模

$(a/b)\ mod\ p=(a*inv[b])\ mod\ p$

一個數 x 在模 p 的條件下不必定有逆元, x 關於 p 的逆元存在 當且僅當 x 和 p 互質

 求逆元的方法:

1.費馬小定理+快速冪

由費馬小定理易得 $a*a^{p-2}\equiv 1(mod\  p)$

因此$a^{p-2}$即爲所求(要求a、p互質!)

2.線性推逆元

求1!~n!的逆元:

$inv[i] =inv[i+1]*(i+1) (mod\ p)$

inline void get_finv()
{
    fac[1]=finv[0]=1;
    for(int i=2;i<=n;++i;++i)
        fac[i]=fac[i-1]*i%mod;
    finv[n]=quick_pow(fac[n],mod-2);
    for(int i=n-1;i;--i)
        finv[i]=finv[i+1]*(i+1)%mod;
}
View Code

 

證實:

 fac[i] * inv[i] 1 (mod p) fac[i+1] * inv[i+1] 1 (mod p) => fac[i]* (i+1) * inv[i+1] 1(mod p)  同餘的除法原理可得 : inv[i] inv[i+1] * (i+1) 推導完畢

 

 

求1~n的逆元:

$inv[i]=inv[p\ mod\ i] * (- p/i) (mod\ p)$

inline void get_inv()
{
    inv[0]=inv[1]=1;
    for(int i=2;i<=n;++i)
        inv[i]=inv[mod%i]*(mod-mod/i)%mod;
}
View Code

證實:

  s = p/i , t = p%i , 則有: s*i + t = p (顯然) 而後 s*i + t  0 (mod p) 移項得 t  -s*i (mod p) 同除以 t * i  t / (t*i)  -s*i / (t*i) (mod p) 將除法轉化爲乘法 => inv[i]  -s * inv[t] (mod p) 因而將 s=p/i , t=p%i帶入就能夠獲得: inv[i]  inv[p%i] * (-p/i) (mod p) 推導完畢

 

 

3.擴展歐幾里得

$axΞ1(mod\ b)$

-->$ax+by=1$

利用擴歐求解

//轉載 from Judge
#define ll long long
const int mod=; //同上
 void ex_gcd(ll a,ll b,ll &x,ll &y){
    if(!b){ x=1,y=0; return ; }
    ex_gcd(b,a%b,x,y);
    ll t=x; x=y,y=t-(a/b)*y;
 }
 //固然你也能夠這麼寫,更能體現公式: 
 //  ll X=x,Y=y;
 //  x=Y,y=X-(a/b)*Y;
 inline ll inv(ll a){
    ll inv_a,y;
    ex_gcd(a,mod,inv_a,y);
    return inv_a;
 }
View Code

 

中國剩餘定理

求解同餘方程組

xΞa1(mod m1)

xΞa2(mod m2)

xΞa3(mod m3)

......

xΞak(mod mk)

其中a1 a2 a3... ak兩兩互質

求x的最小非負整數解

定理內容

令$M=lcm(m_1,m_2,m_3,...m_k)$,即$M=m_1*m_2*m_3*...*m_k$

$t_i$爲 $\frac{M}{m_i} t_i \equiv 1\ (mod\ m_i)$的最小非負整數解

則必有一解爲

$x=\sum \limits _{i=1}^{k} a_i \frac{M}{m_i} t_i$

通解爲$x+i×M$

最小非負整數解爲$(M+x\ mod\ M)\ mod\ M$

 

//ti​同餘式的求解能夠用擴展歐幾里得

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

int china()
{
    int ans=0,lcm=1,x,y;
    for(int i=1;i<=k;++i) lcm*=b[i];
    for(int i=1;i<=k;++i)
    {
        int tp=lcm/b[i];
        exgcd(tp,b[i],x,y);
        x=(x%b[i]+b[i])%b[i];//x要爲最小非負整數解
        ans=(ans+tp*x*a[i])%lcm;
    }
    return (ans+lcm)%lcm;
}
View Code

 

擴展中國剩餘定理

用於解決m1,m2,m3...mn不互質的狀況。

考慮只有m1,m2的狀況:

設解爲x

可得

$x=a_1+k_1*m_1 ; x=a_2+k_2*m_2$

$a_1+k_1*m_1 = a_2+k_2*m_2$

$k_2*m_2-k_1*m_1=a_1-a_2$

形式與擴歐可解的同餘方程十分類似

設g=gcd(m1,m2)

若$a_1-a_2$不是g的倍數 就無解遼(詳見exgcd解同餘方程有解的條件)

不然解這個同餘方程

最終的解$\times \frac{c}{g}$可得$k_1$

由$x=-k_1\times m_1+a_1$解得x

則通解$X=x+k\times lcm(m_1,m_2)$

最終獲得$x=x_0 (mod lcm(m_1,m_2))$

以此類推,解n次擴歐獲得最終解。

 

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
int n;
ll m[N],a[N];
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b)
    {
        x=1;y=0;
        return a;
    }


    ll gcd=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return gcd;
}

ll excrt()
{
    ll x,y,lcm=m[1],ans=a[1],gcd;
    for(int i=2;i<=n;i++)
    {
        gcd=exgcd(lcm,m[i],x,y);
        if((ans-a[i])%gcd)return -1;
        x=(ans-a[i])/gcd*x%m[i];
        ans-=lcm*x;
        lcm=lcm/gcd*m[i];
        ans%=lcm;
    }
    return (ans%lcm+lcm)%lcm;
}
void work()
{
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&m[i],&a[i]);
    cout<<excrt()<<endl;
}
int main()
{
    while(scanf("%d",&n)==1)work();
    return 0;
}
View Code

排列組合

排列數

從n個不一樣元素中取出m個元素(m<=n)的全部不一樣排列的個數。

$A_n^m=n(n-1)(n-2)\cdots(n-m+1)=\frac{n!}{(n-m)!},\quad n,m\in \mathbb{N}^* ,\text{而且}m\leq n$

特別地,規定0!=1.

組合數

從n個不一樣元素中取出m個元素(m<=n)的全部不一樣組合的個數。

$C_n^m=\frac{A_n^m}{A_m^m}=\frac{n(n-1)(n-2)\cdots (n-m+1)}{m!}=\frac{n!}{m!(n-m)!},\quad n,m\in \mathbb{N}^* ,\text{而且}m\leq n$

規定$C_n^0=C_n^n=1$

二項式定理

常見形式

$(x+1)^n=\sum_{i=0}^{n} C(n,i) ~ x^i$

證實:

(x+1)n=(x+1)*(x+1)*...*(x+1)

從這n個(x+1)中選擇n次,每次只可能選出x或1。

那麼答案即爲每次選出n個元素相乘後將結果累加

而從n個(x+1)中選出i個x的狀況數即爲

$C_n^i$

證畢。

 

Lucas定理

定理內容

證實

(咕咕咕)

代碼 

ll C(ll x,ll y,ll mod)
{
    if(x<y)return 0;
    return fac[x]*qpow(fac[y],p-2,p)%p*qpow(fac[x-y],p-2,p)%p;
}
ll lucas(ll x,ll y,ll p)
{
    if(!y)return 1;
    return C(x%p,y%p,p)*lucas(x/p,y/p,p)%p;
}
View Code

 

莫比烏斯反演(強行NOIP前)

兩類基本形式:

$\begin{aligned} &(1).F(n)=\sum_{d|n}f(d)\Rightarrow f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})&\\ &(2).F(n)=\sum_{n|d}f(d)\Rightarrow f(n)=\sum_{n|d}\mu(\frac{d}{n})F(n)(最經常使用)&\\ \end{aligned}$

 

範德蒙恆等式

$\sum_{i=0}^{k} C_n^i C_m^{k-i}=C_{n+m}^k$

φ(n)=n1

相關文章
相關標籤/搜索