数学部分学习

作者 : admin 本文共5665个字,预计阅读时间需要15分钟 发布时间: 2024-06-9 共3人阅读

1、欧拉函数

  • 计算单个值的欧拉函数

    • 基于公式:$phi(n) = n* \frac{p_1-1}{p_1} * \frac{p_2-1}{p_2}*\dots *\frac{p_n-1}{p_n}

      其中

      其中

      其中p_i

      n$的质因数。

    • 写代码用试除法可以快速求解

      O

      (

      s

      q

      r

      t

      (

      n

      )

      )

      O(sqrt(n))

      O(sqrt(n))

  • 筛法求欧拉函数(线性筛)

    • 代码如下:
    for i in range(2,n+1):
        if st[i]==0:
            primes.append(i)
            phi[i]=i-1 # 质数的phi(i)=i-1
        for j in range(len(primes)):
            if primes[j]*i>n:break
            st[primes[j]*i]=1
            if i%primes[j]==0:
                phi[i*primes[j]] = phi[i]*primes[j] # primes[j]是i的质因素数
                break
            phi[i*primes[j]] = phi[i]*(primes[j]-1) # primes[j]不是i的质因数
    
  • 欧拉降幂

    • 基本公式

      a

      b

      {

      a

      b

       

      m

      o

      d

       

      φ

      (

      m

      )

      ,

                   

      g

      c

      d

      (

      a

      ,

      m

      )

      =

      1

      ,

      a

      b

      ,

                                

      g

      c

      d

      (

      a

      ,

      m

      )

      1

      ,

      b

      <

      φ

      (

      m

      )

      ,

          

      (

      m

      o

      d

        

      m

      )

      a

      (

      b

       

      m

      o

      d

       

      φ

      (

      m

      )

      )

      +

      φ

      (

      m

      )

      ,

        

      g

      c

      d

      (

      a

      ,

      m

      )

      1

      ,

      b

      φ

      (

      m

      )

      .

      a^b \equiv \begin{cases} a^{b \ mod \ \varphi(m)}, \ \ \ \ \ \ \ \ \ \ \ \ \ gcd(a,m)=1, \ a^b, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ gcd(a,m)
      ot=1,b<\varphi(m),\ \ \ \ (mod \ \ m)\ a^{(b \ mod \ \varphi(m)) + \varphi(m)}, \ \ gcd(a,m)
      ot =1,b\ge \varphi(m). \end{cases}

      ab

      ab mod φ(m),             gcd(a,m)=1,ab,                          gcd(a,m)=1,b<φ(m),    (mod  m)a(b mod φ(m))+φ(m),  gcd(a,m)=1,bφ(m).

2、乘法逆元

  • 费马小定理求逆元

    • p

      o

      w

      (

      a

      ,

      p

      ,

      p

      2

      )

      pow(a,p,p-2)

      pow(a,p,p2)

  • 扩展欧几里得算法求逆元

    • e

      x

      g

      c

      d

      (

      a

      ,

      p

      ,

      x

      ,

      y

      )

      exgcd(a,p,x,y)

      exgcd(a,p,x,y)

    • 如果求得最大公约数不是1则无解,否则逆元就是

      x

      x%p

      x

    def exgcd(a,b,x,y):
        if b==0:
            return a,1,0
        d,x,y = exgcd(b,a%b,x,y)
        x,y = y,x-a//b*y
        return d,x,y
    

3、中国剩余定理

  • C

    R

    T

    CRT

    CRT中国剩余定理基本形式

    • 中国剩余定理给出了以下的一元线性同余方程组的解:

    {

    x

    a

    1

    (

    m

    o

    d

    m

    1

    )

    x

    a

    2

    (

    m

    o

    d

    m

    2

    )

    x

    a

    n

    (

    m

    o

    d

    m

    n

    )

    \begin{cases} x \equiv a_1 \pmod{m_1} \ x \equiv a_2 \pmod{m_2} \ \qquad \vdots \ x \equiv a_n \pmod{m_n} \end{cases}

    xa1(modm1)xa2(modm2)xan(modmn)

    • 在中国剩余定理中:

      a

      1

      ,

      a

      2

      ,

      ,

      a

      n

      a_1, a_2, \ldots, a_n

      a1,a2,,an 是给定的余数,

      m

      1

      ,

      m

      2

      ,

      ,

      m

      n

      m_1,m_2,\ldots,m_n

      m1,m2,,mn两两互质,如果两两不互质则是扩展中国剩余定理。

  • C

    R

    T

    CRT

    CRT问题的解决方法

    • CRT主要利用

      m

      1

      ,

      m

      2

      ,

      ,

      m

      n

      m_1,m_2,\dots,m_n

      m1,m2,,mn 为两两互质的整数的性质。我们可以令:

      M

      =

      m

      1

      ×

      m

      2

      ×

      ×

      m

      n

      =

      i

      =

      1

      n

      m

      i

      M

      i

      =

      M

      /

      m

      i

      M=m_1 imes m_2 imes \dots imes m_n = \begin{equation} \prod_{i=1}^{n}m_i \end{equation}\ M_i = M/m_i

      M=m1×m2××mn=i=1nmiMi=M/mi
      明显这里的

      M

      i

      M_i

      Mi是和

      m

      i

      m_i

      mi互质的。

    • 接着我们定义逆元:

      t

      i

      =

      M

      i

      1

      t_i = M_i^{-1}

      ti=Mi1

    • 所以我们可以构造出一个解

      x

      0

      x_0

      x0

      x

      0

      =

      i

      =

      1

      n

      a

      i

      M

      i

      t

      i

      x_0 = \sum_{i=1}^{n}a_iM_it_i

      x0=i=1naiMiti

    • 解释

      j

      [

      1

      ,

      n

      ]

      \forall j \in [1,n]

      j[1,n]

      {

      a

      j

      M

      j

      t

      j

      %

      m

      i

      =

      0

            

      j

      i

      a

      j

      M

      j

      t

      j

      %

      m

      i

      =

      a

      i

           

      j

      =

      i

      \begin{cases} a_jM_jt_j \% m_i = 0 \ \ \ \ \ \ j
      eq i \ a_jM_jt_j \% m_i = a_i \ \ \ \ \ j=i \end{cases}

      {ajMjtj%mi=0      j=iajMjtj%mi=ai     j=i

    • 通解就是

      x

      =

      x

      0

      +

      k

      M

      x = x_0 + kM

      x=x0+kM,而CRT问题所求的最小整数解其实就是

      a

      n

      s

      =

      x

      %

      M

      ans = x \% M

      ans=x%M

  • E

    X

    C

    R

    T

    EXCRT

    EXCRT扩展中国剩余定理的基本用法性质

    • 同余方程合并后模数是原来模数的最小公倍数。

    • 合并的流程:

      • 假设前

        k

        1

        k-1

        k1个同余方程合并得到新的方程为:

        x

        =

        r

        1

        (

        m

        o

        d

        M

        )

        x = r_1 \pmod{M}

        x=r1(modM)

        M

        M

        M是前

        k

        1

        k-1

        k1个同余方程模数的最小公倍数,现在需要考虑合并第

        k

        k

        k个方程:

        x

        =

        r

        2

        (

        m

        o

        d

        m

        k

        )

        x = r_2 \pmod{m_k}

        x=r2(modmk)

      • 对于前

        k

        1

        k-1

        k1个同余方程,其通解为

        x

        =

        r

        1

        +

        i

        M

        ,

        i

        Z

        x=r_1+i*M,i \in Z

        x=r1+iM,iZ,接着在通解里面找到一个

        t

        t

        t,使得

        (

        r

        1

        +

        t

        M

        )

        %

        m

        k

        =

        r

        2

        (r_1+t*M) \%m_k=r_2

        (r1+tM)%mk=r2,即可满足第

        k

        k

        k个方程。那么合并后前

        k

        k

        k个同余方程的通解就是

        x

        =

        r

        1

        +

        t

        M

        +

        i

        l

        c

        m

        (

        M

        ,

        m

        k

        )

        ,

         

        i

        Z

        x = r_1 + t*M + i* lcm(M,m_k), \ i \in Z

        x=r1+tM+ilcm(M,mk), iZ
        再对通解模

        l

        c

        m

        (

        M

        ,

        m

        k

        )

        lcm(M,m_k)

        lcm(M,mk) 即可得到新的

        a

        n

        s

        ans

        ans作为前

        k

        k

        k个同余方程的最小整数解。

      • 其中找

        t

        t

        t的过程:

        M

        t

        +

        m

        k

        y

        =

        r

        2

        r

        1

        M*t + m_k*y=r_2-r_1

        Mt+mky=r2r1,其中

        M

        M

        M就是裴蜀等式的

        a

        ,

        t

        a,t

        a,t就是裴蜀等式的

        x

        x

        x,其中

        r

        2

        r

        1

        r_2-r_1

        r2r1要满足

        g

        c

        d

        (

        M

        ,

        m

        k

        )

        (

        r

        2

        r

        1

        )

        gcd(M,m_k)|(r_2-r_1)

        gcd(M,mk)(r2r1),否则无解。

      • 我们先用扩展欧几里得求解出

        M

        t

        +

        m

        k

        y

        =

        g

        c

        d

        (

        M

        ,

        m

        k

        )

        M*t + m_k*y=gcd(M,m_k)

        Mt+mky=gcd(M,mk),顺便求出

        g

        c

        d

        (

        M

        ,

        m

        k

        )

        gcd(M,m_k)

        gcd(M,mk),再将得到的解

        t

        =

        t

        r

        2

        r

        1

        g

        c

        d

        (

        M

        ,

        m

        k

        )

        t = t* \frac{r_2-r_1}{gcd(M,m_k)}

        t=tgcd(M,mk)r2r1,即可求得

        t

        t

        t

4、组合数

  • 方法一:利用递推公式:

    c

    [

    a

    ]

    [

    b

    ]

    =

    c

    [

    a

    1

    ]

    [

    b

    ]

    +

    c

    [

    a

    1

    ]

    [

    b

    1

    ]

    c[a][b] = c[a-1][b]+c[a-1][b-1]

    c[a][b]=c[a1][b]+c[a1][b1]即考虑当前选不选的问题。

    O

    (

    n

    2

    )

    O(n^2)

    O(n2)其中(

    n

    2000

    n \le 2000

    n2000)

  • 方法二:预处理逆元法:根据公式计算:

    C

    a

    b

    =

    a

    !

    (

    a

    b

    )

    !

    b

    !

    C_a^{b} = \frac{a!}{(a-b)!b!}

    Cab=(ab)!b!a! 由于后面数值一般很大会设置一个模数,可以考虑计算出

    f

    a

    c

    [

    i

    ]

    fac[i]

    fac[i]表示

    i

    i

    i的阶乘,

    i

    n

    f

    a

    c

    [

    i

    ]

    infac[i]

    infac[i]表示

    i

    i

    i的阶乘的逆元。因此:

    C

    a

    b

    =

    f

    a

    c

    [

    a

    ]

    i

    n

    f

    a

    c

    [

    a

    b

    ]

    %

    p

    i

    n

    f

    a

    c

    [

    b

    ]

    %

    p

    C_a^{b}=fac[a]*infac[a-b]\%p*infac[b]\%p

    Cab=fac[a]infac[ab]%pinfac[b]%p.此方法可以预处理出$n \le 1e5 $的数。

  • 方法三:利用

    L

    u

    c

    a

    s

    Lucas

    Lucas定理:

    C

    a

    b

    =

    C

    a

    %

    p

    b

    %

    p

    C

    a

    /

    /

    p

    b

    /

    /

    p

     

    (

    m

    o

    d

     

    p

    )

    C_a^{b}=C_{a\%p}^{b\%p}*C_{a//p}^{b//p}\ (mod \ p)

    Cab=Ca%pb%pCa//pb//p (mod p)可以处理(

    1

    b

    a

    1

    0

    18

    1 \le b \le a \le10^{18}

    1ba1018

    p

    p

    p为质数)

    def lucas(a,b,p):
    	if a<p and b<p:return C(a,b,p)
    	return C(a%p,b%p,p)*lucas(a//p,b//p,p)%p
    
    • 应用:括号序列(

      C

      2

      n

      n

      C

      2

      n

      n

      1

      C_{2n}^{n}-C_{2n}^{n-1}

      C2nnC2nn1),这个也称为卡特兰数(合法出栈数)

      • 卡特兰数公式:

        f

        (

        n

        )

        =

        C

        2

        n

        n

        n

        +

        1

        =

        C

        2

        n

        n

        C

        2

        n

        n

        1

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

        f(n)=n+1C2nn=C2nnC2nn1

5、容斥原理

  • 二项式反演:

    • 恰好和至少的转换(常用到)

      • f

        i

        f_i

        fi表示至少有

        k

        k

        k个的方案数,

        g

        i

        g_i

        gi表示恰好有

        k

        k

        k个方案数,则有:

      f

      k

      =

      i

      =

      k

      n

      (

      n

      k

      )

      g

      i

      f_k=\sum_{i=k}^{n} \binom{n}{k}g_i

      fk=i=kn(kn)gi

      • 根据二项式反演则有:

      g

      k

      =

      i

      =

      k

      n

      (

      1

      )

      i

      k

      (

      i

      k

      )

      f

      i

      g_k=\sum_{i=k}^{n}(-1)^{i-k} \binom{i}{k}f_i

      gk=i=kn(1)ik(ki)fi

      • 当我们需要求恰好

        k

        k

        k个方案,同时发现至少

        k

        k

        k个方案比较容易求时可以建议用这个。

    • 恰好和至多的转换(没上面常用)

      • f

        i

        f_i

        fi表示至多有

        k

        k

        k个方案数,

        g

        i

        g_i

        gi表示恰好有

        k

        k

        k个方案数,则有:

      f

      k

      =

      i

      =

      0

      n

      (

      n

      k

      )

      g

      i

      f_k=\sum_{i=0}^{n} \binom{n}{k}g_i

      fk=i=0n(kn)gi

      • 根据二项式反演则有:

      g

      k

      =

      i

      =

      0

      n

      (

      1

      )

      k

      i

      (

      i

      k

      )

      f

      i

      g_k=\sum_{i=0}^{n} (-1)^{k-i} \binom{i}{k}f_i

      gk=i=0n(1)ki(ki)fi

      • 当发现最多有

        k

        k

        k个的时候好算时用这个。

6、博弈论

  • 四种经典组合游戏

    • 尼姆游戏:

      n

      n

      n堆物品,每堆

      a

      i

      a_i

      ai个,两名玩家轮流,每次选一堆,至少取1个最多可全部取走。

      • 结论:令$S=\oplus_{i=1}^n a_i

        先手必胜当且仅当

        先手必胜当且仅当

        先手必胜当且仅当S
        ot =0$.(根据异或性质容易判断)

    • 巴什博弈:

      1

      1

      1堆石子,总数

      n

      n

      n个,两名玩家轮流取,每次至少取1个,最多取m个,取走最后一个的玩家获胜。

      • 结论:可以发现不管怎么取都可以操作出

        m

        +

        1

        m+1

        m+1个石子,所以当

        (

        m

        +

        1

        )

        n

        (m+1)|n

        (m+1)n时先手必败。

    • 威佐夫博弈:

      2

      2

      2堆石子,石子数可以不同,两名玩家轮流取石子,每次可以从一堆中取或从两堆中取走相同个石子。取走最后一个石子的人获胜。

      • 结论:设

        x

        =

        1

        +

        5

        2

        x=\frac{1+\sqrt 5}{2}

        x=21+5

        ,则第

        i

        i

        i个必败态(

        a

        i

        ,

        b

        i

        a_i,b_i

        ai,bi)满足$a_i=\lfloor ix\rfloor

        ,

        ,

        ,b_i=i+a_i=\lfloor ix^2 \rfloor$.

      • 在实际代码中就是

        m

        i

        n

        (

        a

        ,

        b

        )

        =

        i

        n

        t

        (

        a

        b

        s

        (

        a

        b

        )

        1

        +

        5

        2

        )

        min(a,b)= int(abs(a-b)*\frac{1+\sqrt 5}{2})

        min(a,b)=int(abs(ab)21+5

        )则先手必败,反之

        w

        i

        n

        win

        win.

    • 斐波那契博弈:

      1

      1

      1堆石子,总数

      n

      n

      n个,两名玩家轮流取,先手不能一次取完,至少1个,之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍。取走最后一个的获胜。

      • 结论:当且仅当石子个数为斐波那契数时先手必败。
  • N

    i

    m

    S

    G

    Nim-SG

    NimSG函数

    • 尼姆游戏的变种总结出来的规律。

      M

      e

      x

      Mex

      Mex运算:

      m

      e

      x

      (

      S

      )

      =

      min

      {

      x

      N

      x

      ∉

      S

      }

      {

      x

      }

      mex(S)=\min\limits_{\{x \in \mathbb{N} \mid x
      ot \in S \}} \{x\}

      mex(S)={xNxS}min{x}也就是不在

      S

      S

      S集合中的最小自然数

    • S

      G

      SG

      SG函数计算每一个节点的

      s

      g

      sg

      sg值,

      S

      G

      (

      x

      )

      =

      m

      e

      x

      (

      {

      S

      G

      (

      y

      1

      )

      ,

      S

      G

      (

      y

      2

      )

      ,

      ,

      S

      G

      (

      y

      k

      )

      }

      )

      SG(x)=mex(\{SG(y_1),SG(y_2),\dots,SG(y_k)\})

      SG(x)=mex({SG(y1),SG(y2),,SG(yk)}),其中

      y

      1

      ,

      y

      2

      ,

      ,

      y

      k

      y_1,y_2,\dots,y_k

      y1,y2,,yk

      x

      x

      x的后继节点。

      def mex(lst):
          lst = list(set(lst))
          return next((idx for idx,num in enumerate(lst) if idx!=num),lst[-1]+1)
      def SG(lst,n):
          sg = [0]*(n+5)
          for i in range(1,n+1):
              sg[i] = mex([sg[i-j] for j in lst if i-j>=0])
          return sg
      
    • 这个模板基本通用了。

本站无任何商业行为
个人在线分享-虚灵IT资料分享 » 数学部分学习
E-->