FFT离散的快速傅里叶变换及其实现

本文详细介绍了快速傅里叶变换(FFT)的概念,包括其基本原理、单位复数根、DFT与FFT的关系以及FFT算法的实现。FFT通过将多项式拆分为奇数和偶数项,大幅减少了计算复杂度,从θ(n^2)降低到θ(nlgn)。此外,还探讨了IDFT(逆离散傅里叶变换)在多项式乘法中的应用,用于将点值表示转换回系数表示。
摘要由CSDN通过智能技术生成

FFT快速傅里叶变换(离散型)

先说个比较慢的版本便于理解,下次给出迭代的FFT,基于一个叫蝴蝶变换的东西。

读者所需预备知识

  1. 会写出多项式及其相关概念
  2. 知道什么是多项式的系数表示与点值表示
  3. 知道啥叫复数

多项式的表示

  • 多项式 P ( x ) = ∑ i = 0 n − 1 a i ∗ x i P(x)=\sum_{i=0}^{n-1}a_i*x^i P(x)=i=0n1aixi

  • 多项式的次数界大于最高次数的数字,例如说上面的多项式的次数界为 n n n

  • 霍纳法则 P ( x ) = ∑ i = 0 n − 1 a i x i = a 0 + x ( a 1 + x ( a 2 + . . . + x ( a n − 1 ) ) ) P(x)=\sum_{i=0}^{n-1}{a_ix_i}=a_0 + x(a_1+x(a_2+...+x(a_{n-1}))) P(x)=i=0n1aixi=a0+x(a1+x(a2+...+x(an1))),有了霍纳法则我们可以在 θ ( n ) \theta(n) θ(n)的时间内求出多项式的值。

  • 点值表示: { ( x 0 , y 0 ) , ( x 1 , y 1 ) , … , ( x n − 1 , y n − 1 ) } \{(x_0,y_0),(x_1,y_1),\dots,(x_{n-1},y_{n-1})\} {(x0,y0),(x1,y1),,(xn1,yn1)} { ( x 0 , P ( x 0 ) ) , ( x 1 , P ( x 1 ) ) , … , ( x n − 1 , P ( x n − 1 ) ) } \{(x_0,P(x_0)),(x_1,P(x_1)),\dots,(x_{n-1},P(x_{n-1}))\} {(x0,P(x0)),(x1,P(x1)),,(xn1,P(xn1))}

  • 我们能求出一个多项式的 n n n​个点值表达,那么我们能够唯一对应一个多项式系数表达式证明,反之同理(插值)。(即点值和系数存在一一对应关系,可以互相转换

DFT与FFT

在聊DFT之前先看个很重要的东西,必须要理解。

单位复数根

我们断言,如果给多项式 C ( x ) C(x) C(x)​​和 Q ( x ) Q(x) Q(x)​​​代入 n n n​个特殊的点,这些点叫做n次单位复数根或简称n次单位根,那么可以在 θ ( n l g n ) \theta(nlgn) θ(nlgn)​的时间内求出 P ( x ) P(x) P(x)​的点值表式

啥是n次单位根?
  • n n n​​​次单位根是满足 ω n = 1 \omega^n=1 ωn=1​​的复数 ω \omega ω​​​​。注意 ω \omega ω是一个复数,也就是 a + i b a+ib a+ib的形式的东西。

图片来自wiki百科

  • 复数要表示在复平面上,如图这就是一个3次单位根(每个箭头都是一个),其中 ω 3 0 = ω 3 3 = 1 \omega_3^0=\omega_3^3=1 ω30=ω33=1​​,上边这个圆叫单位圆
  • 回忆一下复数的乘法(满足平行四边形法则),是不是辐角相加,模长相乘。在单位圆上由于模长都是1,所以两个单位根相乘,就相当于在把那个箭头做旋转
    • 例如 ω 3 2 ∗ ω 3 1 = ω 3 3 \omega_3^2*\omega_3^1=\omega_3^3 ω32ω31=ω33,就相当于把第二象限的那个箭头旋转到 R \R R轴正方向上
  • 引入欧拉公式如何理解 e i x = cos ⁡ ( x ) + i ∗ sin ⁡ ( x ) e^{ix}=\cos(x)+i*\sin(x) eix=cos(x)+isin(x),将 x = 2 π x=2\pi x=2π(也就是一个圆周)代入得到 e 2 π i = 1 e^{2\pi i}=1 e2πi=1
  • 将圆周分成 n n n​​份,发现这个玩意恰好和单位根定义一样,所以有 ω = e 2 π i n \omega = e^{\frac{2\pi i}{n}} ω=en2πi​,为了方便区分我们把圆分成了几份我们这样记 w n = w w_n=w wn=w
证明几个性质
  1. (消去引理) ω d n d k = ω n k \omega_{dn}^{dk}=\omega_{n}^{k} ωdndk=ωnk,可以理解为把圆分成了 d n dn dn份取 d k dk dk份和圆分成 n n n份取 k k k份取得的面积不变,证明: ω d n d k = ( e 2 π i d n ) d k = ( e 2 π i n ) k = ω n k \omega_{dn}^{dk}=(e^{\frac{2\pi i}{dn}})^{dk}=(e^{\frac{2\pi i}{n}})^{k}=\omega_n^k ωdndk=(edn2πi)dk=(en2πi)k=ωnk
  2. (负方向) ω n n / 2 = − 1 \omega_n^{n/2}=-1 ωnn/2=1​,理解为 n 2 \frac{n}{2} 2n​恰好旋转到 x x x​轴的负方向。
  3. (周期性) ω n 2 k + n = ω n 2 k \omega_n^{2k+n}=\omega_n^{2k} ωn2k+n=ωn2k,理解为我们是在单位圆上旋转 + n +n +n相当于多旋转一圈。
  4. (折半引理) ω n k + n / 2 = − ω n k \omega_n^{k+n/2}=-\omega_n^{k} ωnk+n/2=ωnk,证明: ω n k + n / 2 = ω n n / 2 ∗ ω n k = − 1 ∗ ω n k = − ω n k \omega_n^{k+n/2}=\omega_n^{n/2}*\omega_n^{k}=-1 * \omega_n^{k}=-\omega_n^{k} ωnk+n/2=ωnn/2ωnk=1ωnk=ωnk
    • 推论: ( ω n k + n / 2 ) 2 = ω n 2 k = ω n / 2 k (\omega_n^{k+n/2})^2=\omega_{n}^{2k}=\omega_{n/2}^k (ωnk+n/2)2=ωn2k=ωn/2k,证明: ( ω n k + n / 2 ) 2 = ω n 2 k + n = ω n 2 k = ω n / 2 k (\omega_n^{k+n/2})^2=\omega_n^{2k+n}=\omega_n^{2k}=\omega_{n/2}^k (ωnk+n/2)2=ωn2k+n=ωn2k=ωn/2k
  5. (求和引理) ∑ j = 0 n − 1 ω n k j = ∑ j = 0 n − 1 ( ω n k ) j = 0 \sum_{j=0}^{n-1}\omega_{n}^{kj}=\sum_{j=0}^{n-1}(\omega_{n}^{k})^j=0 j=0n1ωnkj=j=0n1(ωnk)j=0,证明如下: ∑ j = 0 n − 1 ( ω n k ) j = ( ω n k ) n − 1 ω n k − 1 = ( ω n n ) k − 1 ω n k − 1 = 1 k − 1 ω n k − 1 = 0 \sum_{j=0}^{n-1}(\omega_{n}^{k})^j=\frac{(\omega_{n}^{k})^n-1}{\omega_{n}^{k}-1}=\frac{(\omega_{n}^{n})^k-1}{\omega_{n}^{k}-1}=\frac{1^k-1}{\omega_{n}^{k}-1}=0 j=0n1(ωnk)j=ωnk1(ωnk)n1=ωnk1(ωnn)k1=ωnk11k1=0
DFT(系数转点值)

如果我们把 ω n 0 , ω n 1 , ω n 2 , ⋯   , ω n n − 1 \omega_n^0,\omega_n^1,\omega_n^2,\cdots,\omega_n^{n-1} ωn0,ωn1,ωn2,,ωnn1作为 x 0 , x 1 , x 2 , ⋯   , x n − 1 x_0,x1,x_2,\cdots,x_{n-1} x0,x1,x2,,xn1代入 P ( x ) P(x) P(x),定义 y k = P ( ω n k ) = ∑ j = 0 n − 1 a j ∗ ω n k j y_k=P(\omega_n^{k})=\sum_{j=0}^{n-1}a_j*\omega_n^{kj} yk=P(ωnk)=j=0n1ajωnkj

那么向量 y = ( y 0 , y 1 , y 2 , ⋯   , y n − 1 ) y=(y_0,y_1,y_2,\cdots,y_{n-1}) y=(y0,y1,y2,,yn1),就是系数向量 a = ( a 0 , a 1 , a 2 , ⋯   , a n − 1 ) a=(a_0,a_1,a_2,\cdots,a_{n-1}) a=(a0,a1,a2,,an1)离散傅里叶变换(DFT)

y = D F T n ( a ) y=DFT_n(a) y=DFTn(a),表示一个 n n n次数界多项式的离散傅里叶变换。

FFT

如果我们把多项式 P ( x ) P(x) P(x)拆分成两个多项式, P o d d ( x ) P_{odd}(x) Podd(x) P e v e n ( x ) P_{even}(x) Peven(x),分别表示奇数系数项和偶数系数项

  • P o d d ( x ) = a 1 + a 3 x 2 + a 5 x 4 + ⋯ + a n − 1 x n − 2 = u = x 2 a 1 + a 3 u + a 5 u 2 + ⋯ + a n − 1 u n / 2 − 1 P_{odd}(x)=a_1+a_3x^2+a_5x^4+\cdots+a_{n-1}x^{n-2}\overset{u=x^2}{=}a_1+a_3u+a_5u^2+\cdots+a_{n-1}u^{n/2-1} Podd(x)=a1+a3x2+a5x4++an1xn2=u=x2a1+a3u+a5u2++an1un/21

  • P e v e n ( x ) = a 0 + a 2 x 2 + a 4 x 4 + ⋯ + a n − 2 x n − 2 = u = x 2 a 0 + a 2 u + a 4 u 2 + ⋯ + a n − 2 u n / 2 − 1 P_{even}(x)=a_0+a_2x^2+a_4x^4+\cdots+a_{n-2}x^{n-2}\overset{u=x^2}{=}a_0+a_2u+a_4u^2+\cdots+a_{n-2}u^{n/2-1} Peven(x)=a0+a2x2+a4x4++an2xn2=u=x2a0+a2u+a4u2++an2un/21

那么可以发现 P ( x ) = P e v e n ( u ) + x P o d d ( u ) = P e v e n ( x 2 ) + x P o d d ( x 2 ) P(x)=P_{even}(u)+xP_{odd}(u)=P_{even}(x^2)+xP_{odd}(x^2) P(x)=Peven(u)+xPodd(u)=Peven(x2)+xPodd(x2)

总结: P ( x ) = P e v e n ( x 2 ) + x P o d d ( x 2 ) P(x)=P_{even}(x^2)+xP_{odd}(x^2) P(x)=Peven(x2)+xPodd(x2),这表示我们只要求两个次数界为 n 2 − 1 \frac{n}{2}-1 2n1的多项式在 ( ω n 0 ) 2 , ( ω n 1 ) 2 , ( ω n 2 ) 2 , ⋯   , ( ω n n − 1 ) 2 (\omega_n^0)^2,(\omega_n^1)^2,(\omega_n^2)^2,\cdots,(\omega_n^{n-1})^2 (ωn0)2,(ωn1)2,(ωn2)2,,(ωnn1)2处的值,即可得到原多项式的值。由折半引理和它的推论可以得到:
P ( ω n k ) = P e v e n ( ω n / 2 k ) + ω n k P o d d ( ω n / 2 k ) P ( ω n k + n / 2 ) = P e v e n ( ω n / 2 k ) − ω n k P o d d ( ω n / 2 k ) P(\omega_n^{k})=P_{even}(\omega_{n/2}^k)+\omega_n^kP_{odd}(\omega_{n/2}^k) \\ P(\omega_n^{k+n/2})=P_{even}(\omega_{n/2}^k)-\omega_n^kP_{odd}(\omega_{n/2}^k) P(ωnk)=Peven(ωn/2k)+ωnkPodd(ωn/2k)P(ωnk+n/2)=Peven(ωn/2k)ωnkPodd(ωn/2k)
给出FFT的伪代码

def FFT(A):
    # 假设n是2的幂,如果不是向后补位到2的幂
    n = A.length
    if n == 1: return
    # divide
    Peven = (A0,A2,..,An-2)
    Podd  = (A1,A3,..,An-1)
    Yeven = FFT(Peven)
    Yodd  = FFT(Podd)
    # conquer
    Wn = e^(2pi)/n = cos(2pi/n) + sin(2pi/n)
    w = 1
    Y = list()
    # 折半引理和推论
    for k in range(n/2-1):
    	Y[k]     = Yeven[k] + w * Yodd[k]
        Y[k+n/2] = Yeven[k] - w * Yood[k]
        w = w * Wn # 旋转一个单位,相当于辐角+(1/n圆)
        
    return Y
  • 我们通过 F F T ( C ) , F F T ( Q ) FFT(C),FFT(Q) FFT(C)FFT(Q)将两个多项式 C ( x ) , Q ( x ) C(x),Q(x) C(x),Q(x)的系数表达式转变为了点值表达式,也就是求得两多项式的 D F T DFT DFT
IDFT插值(点值转系数)

先抛出结论:证明
I D F T ( y ) = 1 n ∑ k = 0 n − 1 y k ∗ ω n − k j IDFT(y)=\frac{1}{n}\sum_{k=0}^{n-1}y_k*\omega_n^{-kj} IDFT(y)=n1k=0n1ykωnkj

  • 此时我们发现上式其实也是在做 D F T DFT DFT,只不过里边的 ω n k j 变 为 ω n − k j \omega_n^{kj}变为\omega_n^{-kj} ωnkjωnkj,而前边也多了个 1 n \frac{1}{n} n1

    • ω n − k j = e − 2 k π i n = cos ⁡ ( − 2 k π n ) + i sin ⁡ ( − 2 k π n ) = 奇 偶 性 cos ⁡ ( 2 k π n ) − i sin ⁡ ( 2 k π n ) \omega_n^{-kj}=e^{-\frac{2k\pi i}{n}}=\cos(-\frac{2k\pi}{n}) + i\sin(-\frac{2k\pi}{n})\overset{奇偶性}{=}\cos(\frac{2k\pi}{n}) - i\sin(\frac{2k\pi}{n}) ωnkj=en2kπi=cos(n2kπ)+isin(n2kπ)=cos(n2kπ)isin(n2kπ)
    • 这说明 ω n − k j \omega_n^{-kj} ωnkj相当于将 ω n k j \omega_n^{kj} ωnkj虚部取反,实部不变
  • 所以我们考虑改造一下我们的 F F T FFT FFT算法

# inv=-1表示IDFT,inv=1表示DFT
 def FFT(A, inv=1):
     n = A.length
     if n == 1: return
     
     Peven = (A0,A2,..,An-2)
     Podd  = (A1,A3,..,An-1)
     Yeven = FFT(Peven, inv)
     Yodd  = FFT(Podd,  inv)
    
 	 # 注意这里变化了,如果是逆变换虚部要取反
     Wn = e^(2pi)/n = cos(2pi/n) + inv * sin(2pi/n)
     w = 1
     Y = list()
   
     for k in range(n/2-1):
     	 Y[k]     = Yeven[k] + w * Yodd[k]
         Y[k+n/2] = Yeven[k] - w * Yood[k]
         w = w * Wn
         
     return Y

如何调用:

def solve():
    C = (a0, a1, ... , a2)
    Q = (b0, b1, ... , b2)
    # 如果他两的长度不是2的幂,补齐到2的幂
    n = power2(max(C.length,Q.length)) 
    # DFT转点值
    Yc = FFT(C, 1)
    Yq = FFT(Q, 1)
    Y = list()
    # 点值乘法 P(i) = C(i) * Q(i)
    for i in range(n):
        Y[i] = Yc[i] * Yq[i]
    # a = IDFT(Y)
    a = FFT(Y, -1)
    return a

思路总结:

要求 P ( x ) = C ( x ) ∗ Q ( x ) P(x)=C(x)*Q(x) P(x)=C(x)Q(x)

  1. 如果我们能通过选取一系列特殊的点使得求出点值表达式的时间加快,具体来说时间复杂度为 θ ( n l g n ) \theta(nlgn) θ(nlgn)
  2. 对点值进乘法运算,使用 θ ( n ) \theta(n) θ(n)的时间
    • 可以得到 P ( x i ) = C ( x i ) ∗ Q ( x i ) P(x_i)=C(x_i)*Q(x_i) P(xi)=C(xi)Q(xi)
    • 可以的到P的点值表示形式: P ( x ) = { ( x 0 , C ( x 0 ) ∗ Q ( x 0 ) ) , ⋯   , ( x n − 1 , C ( x n − 1 ) ∗ Q ( x n − 1 ) ) } P(x)=\{(x_0, C(x_0)*Q(x_0)),\cdots,(x_{n-1}, C(x_{n-1})*Q(x_{n-1}))\} P(x)={(x0,C(x0)Q(x0)),,(xn1,C(xn1)Q(xn1))}
  3. 将得到的P的点值表达式通过 I D F T IDFT IDFT转换为系数表达式,时间复杂度 θ ( n l g n ) \theta(nlgn) θ(nlgn)
  4. 总之就是如下图

算法导论

一些需要的证明

  • 证明(多项式插值的唯一性)

    • 把第一个矩阵每一行看成一个多项式每一项代入的未知量,第二个矩阵看成多项式的系数
      那么由矩阵乘法可以推出所有的多项式的值(用第一个矩阵的每一行乘第二个矩阵的每一列)。

    [ 1 x 0 x 0 2 ⋯ x 0 n − 1 1 x 1 x 1 2 ⋯ x 1 n − 1 1 x 2 x 2 2 ⋯ x 2 n − 1 ⋮ ⋮ ⋮ ⋱ ⋮ 1 x n − 1 x n − 1 2 ⋯ x n − 1 n − 1 ] ∗ [ a 0 a 1 a 2 ⋯ a n − 2 a n − 1 ] = [ y 0 y 1 y 2 ⋯ y n − 2 y n − 1 ] \left[ \begin{matrix} 1 & x_0 & x_0^2 & \cdots & x_0^{n-1} \\ 1 & x_1 & x_1^2 & \cdots & x_1^{n-1} \\ 1 & x_2 & x_2^2 & \cdots & x_2^{n-1} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & x_{n-1} & x_{n-1}^2 & \cdots & x_{n-1}^{n-1} \\ \end{matrix} \right] * \left[ \begin{matrix} a_0 \\ a_1 \\ a_2 \\ \cdots \\ a_{n-2} \\ a_{n-1} \\ \end{matrix} \right] = \left[ \begin{matrix} y_0 \\ y_1 \\ y_2 \\ \cdots \\ y_{n-2} \\ y_{n-1} \\ \end{matrix} \right] 1111x0x1x2xn1x02x12x22xn12x0n1x1n1x2n1xn1n1a0a1a2an2an1=y0y1y2yn2yn1

    • 第一个矩阵叫做范德蒙(Vandermonde)矩阵,由线性代数的知识我们知道他是可逆的。
    • 那么给等号右边的值矩阵乘以范德蒙矩阵的逆矩阵就可以推出系数矩阵,这代表两个矩阵可以互相转化

  • 证明(IDFT的推导)

    • 写出将单位根代入多项式后的矩阵相乘的形式

    [ 1 1 1 ⋯ 1 1 ω n ω n 2 ⋯ ω n n − 1 1 ω n 2 ω n 4 ⋯ ω n 2 ( n − 1 ) ⋮ ⋮ ⋮ ⋱ ⋮ 1 ω n n − 1 ω n 2 ( n − 1 ) ⋯ ω n ( n − 1 ) ( n − 1 ) ] ∗ [ a 0 a 1 a 2 ⋯ a n − 2 a n − 1 ] = [ y 0 y 1 y 2 ⋯ y n − 2 y n − 1 ] \left[ \begin{matrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & \omega_n & \omega_n^2 & \cdots & \omega_n^{n-1} \\ 1 & \omega_n^2 & \omega_n^4 & \cdots & \omega_n^{2(n-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_n^{n-1} & \omega_n^{2(n-1)} & \cdots & \omega_n^{(n-1)(n-1)} \\ \end{matrix} \right] * \left[ \begin{matrix} a_0 \\ a_1 \\ a_2 \\ \cdots \\ a_{n-2} \\ a_{n-1} \\ \end{matrix} \right] = \left[ \begin{matrix} y_0 \\ y_1 \\ y_2 \\ \cdots \\ y_{n-2} \\ y_{n-1} \\ \end{matrix} \right] 11111ωnωn2ωnn11ωn2ωn4ωn2(n1)1ωnn1ωn2(n1)ωn(n1)(n1)a0a1a2an2an1=y0y1y2yn2yn1

    • 记左1矩阵为: V n V_n Vn(表示n阶范德蒙矩阵),左2矩阵为: a a a (表示多项式的系数矩阵),右1矩阵为: y y y (表示多项式的值矩阵)

    • 那么我们就是要求 a a a,也就是给等号两边同时乘以 V n V_n Vn的逆矩阵 V n − 1 V_n^{-1} Vn1,那么这个逆矩阵该如何表示呢?

    • 定理: V n − 1 V_n^{-1} Vn1对于 j , k = 0 , 1 , ⋯   , n − 1 j,k=0,1,\cdots,n-1 j,k=0,1,,n1的行标为 j j j,列标为 k k k处的元素为 ω n − k j / n \omega_n^{-kj}/{n} ωnkj/n

      要证上边的定理成立,就是要证明 V n − 1 V n = I n V_n^{-1}V_n=I_n Vn1Vn=In,其中 I n I_n In n n n单位阵

      考虑 ( i , j ) (i,j) (i,j)处的元素:
      [ V n − 1 V n ] i j = ∑ k = 0 n − 1 ( ω n − k i n ) ω n k j ) = ∑ k = 0 n − 1 ω n k ( j − i ) [V_n^{-1}V_n]_{ij}=\sum_{k=0}^{n-1}(\frac{\omega_n^{-ki}}{n})\omega_n^{kj})=\sum_{k=0}^{n-1}\omega_n^{k(j-i)} [Vn1Vn]ij=k=0n1(nωnki)ωnkj)=k=0n1ωnk(ji)
      如果 i = j i=j i=j则上式的和为1(主对角线上元素为1),否则根据求和引理该和为0,那么乘积的结果为:
      [ 1 0 0 ⋯ 0 0 1 0 ⋯ 0 0 0 1 ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ 1 ] \left[ \begin{matrix} 1 & 0 & 0 & \cdots & 0 \\ 0 & 1 & 0 & \cdots & 0 \\ 0 & 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 1 \\ \end{matrix} \right] 1000010000100001
      这恰好是单位矩阵 I n I_n In,得证。

    • 那么就有下式成立:
      a = V n − 1 y = ∑ k = 0 n − 1 ω n − k j n ∗ y k = 1 n ∑ k = 0 n − 1 y k ∗ ω n − k j a=V_n^{-1}y=\sum_{k=0}^{n-1}\frac{\omega_n^{-kj}}{n}*y_k=\frac{1}{n}\sum_{k=0}^{n-1}y_k*\omega_n^{-kj} a=Vn1y=k=0n1nωnkjyk=n1k=0n1ykωnkj

  • (简单理解欧拉公式)
    • e i x = cos ⁡ ( x ) + i sin ⁡ ( x ) e^{ix} = \cos(x) + i\sin(x) eix=cos(x)+isin(x),其实就是把一个复数在复平面上对着 R \R R轴和 I I I轴做投影, R \R R轴投影叫做 cos ⁡ ( x ) \cos(x) cos(x), I I I轴投影叫做 i sin ⁡ ( x ) i\sin(x) isin(x),然后数学家恰好发现这些东西等于 e i x e^{ix} eix(可以用泰勒展开验证,详见下边链接)。
    • 深入理解请参考:欧拉公式
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值