数学部分学习

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))
  • 筛法求欧拉函数(线性筛)

    • 代码如下:
    Python 复制代码
    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) \not=1,b<\varphi(m),\ \ \ \ (mod \ \ m)\\ a^{(b \ mod \ \varphi(m)) + \varphi(m)}, \ \ gcd(a,m) \not =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,p−2)
  • 扩展欧几里得算法求逆元

    • e x g c d ( a , p , x , y ) exgcd(a,p,x,y) exgcd(a,p,x,y)
    • 如果求得最大公约数不是1则无解,否则逆元就是 x x%p x
    python 复制代码
    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} ⎩ ⎨ ⎧x≡a1(modm1)x≡a2(modm2)⋮x≡an(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 \times m_2 \times \dots \times m_n = \begin{equation} \prod_{i=1}^{n}m_i \end{equation}\\ M_i = M/m_i M=m1×m2×⋯×mn=i=1∏nmiMi=M/mi

      明显这里的 M i M_i Mi是和 m i m_i mi互质的。

    • 接着我们定义逆元:
      t i = M i − 1 t_i = M_i^{-1} ti=Mi−1

    • 所以我们可以构造出一个解 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=1∑naiMiti

    • 解释 ∀ 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\neq 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 k−1个同余方程合并得到新的方程为: x = r 1 ( m o d M ) x = r_1 \pmod{M} x=r1(modM) , M M M是前 k − 1 k-1 k−1个同余方程模数的最小公倍数,现在需要考虑合并第 k k k个方程: x = r 2 ( m o d m k ) x = r_2 \pmod{m_k} x=r2(modmk)。

      • 对于前 k − 1 k-1 k−1个同余方程,其通解为 x = r 1 + i ∗ M , i ∈ Z x=r_1+i*M,i \in Z x=r1+i∗M,i∈Z,接着在通解里面找到一个 t t t,使得 ( r 1 + t ∗ M ) % m k = r 2 (r_1+t*M) \%m_k=r_2 (r1+t∗M)%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+t∗M+i∗lcm(M,mk), i∈Z

        再对通解模 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 M∗t+mk∗y=r2−r1,其中 M M M就是裴蜀等式的 a , t a,t a,t就是裴蜀等式的 x x x,其中 r 2 − r 1 r_2-r_1 r2−r1要满足 g c d ( M , m k ) ∣ ( r 2 − r 1 ) gcd(M,m_k)|(r_2-r_1) gcd(M,mk)∣(r2−r1),否则无解。

      • 我们先用扩展欧几里得求解出 M ∗ t + m k ∗ y = g c d ( M , m k ) M*t + m_k*y=gcd(M,m_k) M∗t+mk∗y=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=t∗gcd(M,mk)r2−r1,即可求得 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[a−1][b]+c[a−1][b−1]即考虑当前选不选的问题。 O ( n 2 ) O(n^2) O(n2)其中( n ≤ 2000 n \le 2000 n≤2000)

  • 方法二:预处理逆元法:根据公式计算: C a b = a ! ( a − b ) ! b ! C_a^{b} = \frac{a!}{(a-b)!b!} Cab=(a−b)!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[a−b]%p∗infac[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%p∗Ca//pb//p (mod p)可以处理( 1 ≤ b ≤ a ≤ 1 0 18 1 \le b \le a \le10^{18} 1≤b≤a≤1018, p p p为质数)

    python 复制代码
    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} C2nn−C2nn−1),这个也称为卡特兰数(合法出栈数)
      • 卡特兰数公式: 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=C2nn−C2nn−1

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=k∑n(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=k∑n(−1)i−k(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=0∑n(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=0∑n(−1)k−i(ki)fi

      • 当发现最多有 k k k个的时候好算时用这个。

6、博弈论

  • 四种经典组合游戏

    • 尼姆游戏: n n n堆物品,每堆 a i a_i ai个,两名玩家轮流,每次选一堆,至少取1个最多可全部取走。
      • 结论:令S=\\oplus_{i=1}\^n a_i 先手必胜当且仅当 先手必胜当且仅当 先手必胜当且仅当S\\not =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(a−b)∗21+5 )则先手必败,反之 w i n win win.
    • 斐波那契博弈: 1 1 1堆石子,总数 n n n个,两名玩家轮流取,先手不能一次取完,至少1个,之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍。取走最后一个的获胜。
      • 结论:当且仅当石子个数为斐波那契数时先手必败。
  • N i m − S G Nim-SG Nim−SG函数

    • 尼姆游戏的变种总结出来的规律。 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 \not \in S \}} \{x\} mex(S)={x∈N∣x∈S}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的后继节点。

      python 复制代码
      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
    • 这个模板基本通用了。

相关推荐
这个男人是小帅7 分钟前
【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本
人工智能·pytorch·python·深度学习·分类
__基本操作__9 分钟前
边缘提取函数 [OPENCV--2]
人工智能·opencv·计算机视觉
xiaoyaolangwj10 分钟前
高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质
学习·机器人·自动驾驶
Doctor老王13 分钟前
TR3:Pytorch复现Transformer
人工智能·pytorch·transformer
热爱生活的五柒14 分钟前
pytorch中数据和模型都要部署在cuda上面
人工智能·pytorch·深度学习
静止了所有花开1 小时前
SpringMVC学习笔记(二)
笔记·学习
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
HyperAI超神经2 小时前
【TVM 教程】使用 Tensorize 来利用硬件内联函数
人工智能·深度学习·自然语言处理·tvm·计算机技术·编程开发·编译框架
L_cl3 小时前
Python学习从0到1 day26 第三阶段 Spark ④ 数据输出
学习
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python