【Code】转置

本文详细介绍了线性算法的转置原理,包括矩阵乘法、多点求值、简单函数复合等,并通过实例展示了如何利用转置原理优化计算过程。此外,还讨论了转置原理在加法卷积、DFT、多点求值算法中的应用,以及在随机游走问题中的解决方案。
摘要由CSDN通过智能技术生成

转置原理

**线性算法:**有一个 n × n n\times n n×n的矩阵 M M M,输入一个 n n n维向量 a a a,计算 b = M a b=Ma b=Ma的过程叫线性算法。

具体的,若一个算法只包含以下三种操作,那么其就是线性算法:

  • x ← x + c y x\leftarrow x+cy xx+cy
  • s w a p ( x , y ) swap(x,y) swap(x,y)
  • x ← c x x\leftarrow cx xcx

**线性算法的转置:**对于一个计算 b = M a b=Ma b=Ma的线性算法,其转置就是输入 b b b,计算 a = M T b a=M^{T}b a=MTb

转置原理是指:若我们能在一定时间复杂度内完成一个线性算法,那么一定能在同样的时间复杂度内完成其转置。

我们将 M M M分解成一系列初等矩阵 M = E 1 E 2 ⋯ E r M=E_1E_2\cdots E_r M=E1E2Er,那么 M T = E r T E r − 1 T ⋯ E 1 T M^{T}=E_r^{T}E_{r-1}^T\cdots E_1^T MT=ErTEr1TE1T

因此转置一个算法就是将原算法倒着执行,同时每一个基本运算都进行转置。

一些例子

DFT的转置

D F T DFT DFT本质是乘上了一个范德蒙德矩阵,其是对称的,因此其转置就是本身。

这个可以用来去掉蝴蝶变换。

加法卷积的转置

H = F × G H=F\times G H=F×G中的 F F F看成输入, G G G看成常量,那么 H k = ∑ i = 0 G k − i F i H_k=\sum_{i=0}G_{k-i}F_i Hk=i=0GkiFi

那么 H = A F H=AF H=AF的矩阵为 A i , j = [ i ≥ j ] G i − j A_{i,j}=[i\geq j]G_{i-j} Ai,j=[ij]Gij

即转置后为 H ′ = A T F H'=A^TF H=ATF,有:
H k ′ = ∑ i = 0 A k , i T F i = ∑ i = 0 A i , k F i = ∑ i = k G i − k F i = ∑ i = 0 G i F i + k \begin{aligned} H_k'=\sum_{i=0}A^T_{k,i}F_i=\sum_{i=0}A_{i,k}F_i=\sum_{i=k}G_{i-k}F_i=\sum_{i=0}G_iF_{i+k} \end{aligned} Hk=i=0Ak,iTFi=i=0Ai,kFi=i=kGikFi=i=0GiFi+k
即减法卷积,下面记为 × T \times ^T ×T

多点求值

原多点求值算法为考虑 F ( x 0 ) = F ( x )   m o d   ( x − x 0 ) F(x_0)=F(x)\bmod (x-x_0) F(x0)=F(x)mod(xx0),以此分治做多项式取模,常数较大。

我们将多点求值写成矩阵相乘的形式:
( f ( a 1 ) ⋮ f ( a n ) ) = ( 1 a 1 ⋯ a 1 n − 1 ⋮ ⋱ ⋱ ⋮ 1 ⋯ ⋯ a n n − 1 ) ( f 0 ⋮ f n − 1 ) \begin{pmatrix}f(a_1)\\\vdots\\f(a_n)\end{pmatrix}=\begin{pmatrix}1&a_1&\cdots&a_1^{n-1 }\\\vdots&\ddots&\ddots&\vdots\\1&\cdots&\cdots &a_n^{n-1}\end{pmatrix}\begin{pmatrix}f_0\\\vdots\\f_{n-1}\end{pmatrix} f(a1)f(an)=11a1a1n1ann1f0fn1
其转置即为:
( 1 ⋯ 1 a 1 ⋯ a n ⋮ ⋱ ⋮ a 1 n − 1 ⋯ a n n − 1 ) ( g 1 ⋮ g n ) \begin{pmatrix}1&\cdots&1\\a_1&\cdots&a_n\\\vdots&\ddots&\vdots\\a_1^{n-1}&\cdots &a_n^{n-1}\end{pmatrix}\begin{pmatrix}g_1\\\vdots\\g_{n}\end{pmatrix} 1a1a1n11anann1g1gn
=最后第 i i i项为 ∑ j = 1 n g j a j i = ∑ j = 1 n g j   [ x i ] 1 1 − a j x = [ x i ] ∑ j = 1 n g j 1 − a j x \sum_{j=1}^ng_ja_j^i=\sum_{j=1}^n g_j\ [x^i]\dfrac{1}{1-a_jx}=[x^i]\sum_{j=1}^n\dfrac{g_j}{1-a_jx} j=1ngjaji=j=1ngj [xi]1ajx1=[xi]j=1n1ajxgj

这个是较为简单的,我们分治时维护当前区间答案为 A ( x ) B ( x ) \dfrac{A(x)}{B(x)} B(x)A(x),合并左右区间即 A l ( x ) B r ( x ) + A r ( x ) B l ( x ) B l ( x ) B r ( x ) \dfrac{A_{l}(x)B_{r}(x)+A_{r}(x)B_{l}(x)}{B_l(x)B_r(x)} Bl(x)Br(x)Al(x)Br(x)+Ar(x)Bl(x)

注意,整个算法中 g g g为输入,因此 B B B是个常多项式,可以预先预处理,同时转置算法时我们不需要转置它。

我们完整的描述一下这个算法:

  • 首先预处理 B B B,然后开始分治

  • 向左右区间分治

  • 计算 A l ( x ) B r ( x ) , A r ( x ) B l ( x ) A_{l}(x)B_{r}(x),A_{r}(x)B_{l}(x) Al(x)Br(x),Ar(x)Bl(x)并相加

  • 最后根上的多项式乘 B [ 1 , n ] B_{[1,n]} B[1,n]即所求

将其转置:

  • 预处理 B B B,将传入的多项式 A A A转置乘 B [ 1 , n ] ( x ) − 1 B_{[1,n]}(x)^{-1} B[1,n](x)1
  • 将信息下传, A r = A × T B l , A l = A × T B r A_r=A\times^TB_l,A_l=A\times^TB_r Ar=A×TBl,Al=A×TBr
  • 不断分治,最后到叶子都是常数项,即所求的点值。

整个过程只需要一次求逆即可。

code

例题

Contest #2 真实无妄她们的人生之路

n n n件物品,第 i i i件物品属性为 p i p_i pi

主人公等级初始为 0 0 0,使用第 i i i件物品会有 p i p_i pi的概率让等级加一, 1 − p i 1-p_i 1pi 的概率不变。

若最后等级为 j j j,则会具有 a j a_j aj 的攻击力。

f i f_i fi 表示使用除 i i i外的 n − 1 n-1 n1个物品后的期望攻击力。要求求出 f 1 , f 2 , ⋯   , f n f_1,f_2, \cdots ,f_n f1,f2,,fn。答案对 998244353 998244353 998244353 取模。

n ≤ 1 0 5 n\leq 10^5 n105

gym102978 Do Use FFT

给出长为 n n n的序列 a , b , c a,b,c a,b,c,对于 k ∈ [ 1 , n ] k\in [1,n] k[1,n]求出:
∑ i = 1 n ( c i ∏ j = 1 k ( a i + b j ) ) \sum_{i=1}^n(c_i\prod_{j=1}^k(a_i+b_j)) i=1n(cij=1k(ai+bj))
n ≤ 2.5 × 1 0 5 n\leq 2.5\times 10^5 n2.5×105,时限 10 s 10s 10s

code

F i ( x ) = ∏ j = 1 i ( x + b j ) F_i(x)=\prod_{j=1}^i(x+b_j) Fi(x)=j=1i(x+bj),将上式转化为矩阵的形式:
( [ x 0 ] F 1 ( x ) ⋯ [ x n ] F 1 ( x ) [ x 0 ] F 2 ( x ) ⋯ [ x n ] F 2 ( x ) ⋮ ⋱ ⋮ [ x 0 ] F n ( x ) ⋯ [ x n ] F n ( x ) ) ( a 1 0 ⋯ a n 0 a 1 1 ⋯ a n 2 ⋮ ⋱ ⋮ a 1 n ⋯ a n n ) ( c 1 c 2 ⋮ c n ) \begin{pmatrix}[x^0]F_1(x)& \cdots&[x^n]F_1(x)\\ [x^0]F_2(x)& \cdots&[x^n]F_2(x)\\\vdots&\ddots&\vdots\\ [x^0]F_n(x)& \cdots&[x^n]F_n(x)\end{pmatrix}\begin{pmatrix}a_1^0& \cdots& a_n^0\\ a_1^1& \cdots&a_n^2\\\vdots&\ddots&\vdots\\ a_1^n& \cdots&a_n^n\end{pmatrix}\begin{pmatrix}c_1\\c_2\\\vdots\\c_n\end{pmatrix} [x0]F1(x)[x0]F2(x)[x0]Fn(x)[xn]F1(x)[xn]F2(x)[xn]Fn(x)a10a11a1nan0an2annc1c2cn
右边两个即 ∑ i = 1 n c i 1 − a i x \sum_{i=1}^n\dfrac{c_i}{1-a_ix} i=1n1aixci,分治fft计算即可,下面记为 f f f

剩下的我们用转置原理,考虑转置后求的是什么: a n s i = [ x i ] ∑ j = 1 n F j ( x ) f j ans_i=[x_i]\sum_{j=1}^n F_j(x)f_j ansi=[xi]j=1nFj(x)fj

这个可以分治fft解决,记 F l , r = ∏ i = l r ( x + b i ) , A l , r = ∑ i = l r f i F l , i ( x ) F_{l,r}=\prod_{i=l}^r(x+b_i),A_{l,r}=\sum_{i=l}^rf_iF_{l,i}(x) Fl,r=i=lr(x+bi),Al,r=i=lrfiFl,i(x)

F F F f f f无关,可以先预处理。 A l , r = A l , m i d + A m i d + 1 , r F l , r A_{l,r}=A_{l,mid}+A_{mid+1,r}F_{l,r} Al,r=Al,mid+Amid+1,rFl,r

叶子为 f i × ( x + b i ) f_i\times(x+b_i) fi×(x+bi)

再将其转置回去,这个流程为:

  • 初始 A 1 , n = f A_{1,n}=f A1,n=f,同时预处理 F F F
  • A l = A , A r = A × T F l A_{l}=A,A_r=A\times^T F_l Al=A,Ar=A×TFl
  • 递归左右儿子,最后到叶子时 a n s i = A × T ( x + b i ) ans_i=A\times^T(x+b_i) ansi=A×T(x+bi),即 [ x 0 ] A ⋅ b i + [ x 1 ] A [x^0]A\cdot b_i+[x^1]A [x0]Abi+[x1]A

简单函数的复合

G ( x ) G(x) G(x)是一个简单函数,那么我们能在较少的时间内算出 F ( G ( x ) )   m o d   x n F(G(x))\bmod x^{n} F(G(x))modxn

我们认为简单函数有下面几种:

1.加法

F ( x + k ) = ∑ i = 0 n − 1 F i ( x + k ) i = ∑ i = 0 n − 1 F i ∑ j = 0 i ( i j ) x j k i − j = ∑ j = 0 n − 1 x j j ! ∑ i = j n − 1 F i ⋅ i ! k i − j ( i − j ) ! F(x+k)=\sum_{i=0}^{n-1}F_i(x+k)^i=\sum_{i=0}^{n-1}F_i\sum_{j=0}^i\binom{i}{j}x^jk^{i-j}=\sum_{j=0}^{n-1}\frac{x^j}{j!}\sum_{i=j}^{n-1}F_i\cdot i!\frac{k^{i-j}}{(i-j)!} F(x+k)=i=0n1Fi(x+k)i=i=0n1Fij=0i(ji)xjkij=j=0n1j!xji=jn1Fii!(ij)!kij

一次卷积即可。

2.乘法

F ( k x ) F(kx) F(kx),线性乘一边即可。

3.幂

F ( x k ) F(x^k) F(xk),下标变换

4.逆元

F R ( x ) = x n − 1 F ( x − 1 ) F^{R}(x)=x^{n-1}F(x^{-1}) FR(x)=xn1F(x1),那么 F ( x − 1 ) = F R ( x ) × x 1 − n F(x^{-1})=F^R(x)\times x^{1-n} F(x1)=FR(x)×x1n

一次求逆即可。

5.开 k k k次根

x x x对应后面的幂级数是 g g g,且 g = h k g=h^k g=hk。我们将 F F F的下标按模 k k k分类:
F i ( x ) = ∑ j F j k + i x j F_i(x)=\sum_j F_{jk+i} x^j Fi(x)=jFjk+ixj
那么有:
F ( h ) = ∑ i F i ( g ) h i F(h)=\sum_i F_i(g)h^i F(h)=iFi(g)hi
求出 h h h后将其拼起来即可。

6.指数

F ( e x ) = ∑ i = 0 n − 1 F i e i x = ∑ i = 0 n − 1 F i ∑ j i j j ! x j = ∑ j x j j ! ∑ i F i i j F(e^x)=\sum_{i=0}^{n-1}F_ie^{ix}=\sum_{i=0}^{n-1}F_i\sum_j \frac{i^j}{j!}x^j=\sum_j \frac{x^j}{j!}\sum_iF_ii^j F(ex)=i=0n1Fieix=i=0n1Fijj!ijxj=jj!xjiFiij

考虑计算:
∑ j x j ∑ i F i i j \sum_jx^j\sum_{i}F_ii^j jxjiFiij
这个就是刚才多点求值的转置。

7.对数

直接不好考虑,我们考虑复合指数的逆,复合指数可以描述为对 F F F进行多点求值的转置,然后每个位置乘 1 j ! \frac{1}{j!} j!1,将其转置就是先乘 1 j ! \frac{1}{j!} j!1,在进行多点求值,其逆就是多点插值后每个位置乘 j ! j! j!,在将这个算法转置回去即可。

用途

我们考虑一个线性变换 M a = b Ma=b Ma=b,考虑 M M M对应的二元生成函数 F ( x , y ) F(x,y) F(x,y),若其可以表示为 u ( x ) v ( y ) f ( g ( x ) h ( y ) ) u(x)v(y)f(g(x)h(y)) u(x)v(y)f(g(x)h(y))其中 g , h g,h g,h为常数个简单函数复合而成,那么我们可以快速计算 M a Ma Ma

先假设 u = v = 1 u=v=1 u=v=1,那么有:
M i , j = ∑ k g i k f k h j k a n s i = ∑ j a j ∑ k g i k f k h j k M_{i,j}=\sum_kg_i^kf_kh^k_j\\ ans_i=\sum_ja_j\sum_kg_i^kf_kh^k_j Mi,j=kgikfkhjkansi=jajkgikfkhjk
即三个线性变换的复合 g g g复合,点乘 f f f h h h复合的转置。

加上 u , v u,v u,v后原线性变换变为三个线性变换的复合:乘 u u u,原线性变换,乘 v v v的转置

随机游走

在一个无穷大的二维平面上,一个人出发点是 ( 0 , 0 ) (0, 0) (0,0),每步可以沿向量 ( 1 , 1 ) (1, 1) (1,1)$(1, 0) 和 和 (2, 0)$走,分别带有 1 , a , b 1, a, b 1,a,b 的权值;
此人随时可以停止。若停在 ( x , y ) (x, y) (x,y),则会产生 w y w_y wy的权值;
定义一条路径的权是这些权值的乘积。对于 a ∈ [ 1 , n ] a\in[1,n] a[1,n],求出结束在 x x x坐标为 a a a的所有点的所有路径权值之和 g a g_a ga

n ≤ 1 0 5 n\leq 10^5 n105,对 998244353 998244353 998244353取模

f x , y f_{x,y} fx,y表示到达 x , y x, y x,y的路径权值和, f 0 , 0 = 1 f_{0,0}=1 f0,0=1,有 f i , j = f i − 1 , j − 1 + a f i − 1 , j + b f i − 2 , j f_{i,j}=f_{i-1,j-1}+af_{i-1,j}+bf_{i-2,j} fi,j=fi1,j1+afi1,j+bfi2,j

最后 g a = ∑ y f a , y w y g_a=\sum_yf_{a,y}w_y ga=yfa,ywy

f f f的二元生成函数为 F ( x , y ) F(x,y) F(x,y),那么有: F = 1 + x y F + a x F + b x 2 F F=1+xyF+axF+bx^2F F=1+xyF+axF+bx2F,可解得:
F = 1 1 − ( a + y ) x − x 2 = 1 ( 1 − x 2 ) ( 1 − a + y 1 − x 2 ) F=\frac{1}{1-(a+y)x-x^2}=\frac{1}{(1-x^2)(1-\frac{a+y}{1-x^2})} F=1(a+y)xx21=(1x2)(11x2a+y)1
写成上面的形式即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值