多项式相关&&生成函数相关&&一些题目(updating...)

版权声明:随意转载哦......但还是请注明出处吧: https://blog.csdn.net/dreaming__ldx/article/details/85372365

多项式乘法

这个大家应该都会吧
还是推一推吧。
已知的:
A ( x ) = i = 0 n a i x i A(x)=\sum_{i=0}^na_ix^i
B ( x ) = i = 0 m b i x i B(x)=\sum_{i=0}^mb_ix^i
要求的:
C ( x ) = A ( x ) B ( x ) = i = 0 n + m ( j = 0 m i n { i , n } a j b i j ) x i C(x)=A(x)B(x)=\sum_{i=0}^{n+m}(\sum_{j=0}^{min\{i,n\}}a_j*b_{i-j})x^i

显然直接暴力做是 O ( n 2 ) O(n^2) 的,考虑如何优化。

那么我们使用 f f t fft 或者 n t t ntt 来实现点值表示法和系数表示法之间的快速转化。

为了方便起见,我们将 A , B A,B 的最高次数统一成一个 2 2 的幂(对于超过 n / m n/m 的项次数看成0即可)

所谓的系数表示法就是我们平常用的那种。

而点值表示法,就是把这个多项式理解成一个函数,用这个函数上的若干个点的坐标来描述这个多项式:
f ( x ) = ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n , y n ) = p 0 , p 1 , p 2 , . . . , p n f(x)=(x_0,y_0),(x_1,y_1),...,(x_n,y_n)=p_0,p_1,p_2,...,p_n

假设我们已经将 A , B A,B 两个函数转化成了点值表示,于是就可以马上求出 C C 的点值表示:
A ( x ) = ( x a , 0 , y a , 0 ) , ( x a , 1 , y a , 1 ) , . . . , ( x a , n 1 , y a , n 1 ) = p a , 0 , p a , 1 , . . . , p a , n 1 A(x)=(x_{a,0},y_{a,0}),(x_{a,1},y_{a,1}),...,(x_{a,n-1},y_{a,n-1})=p_{a,0},p_{a,1},...,p_{a,n-1}
B ( x ) = ( x b , 0 , y b , 0 ) , ( x b , 1 , y b , 1 ) , . . . , ( x b , n 1 , y b , n 1 ) = p b , 0 , p b , 1 , . . . , p b , n 1 B(x)=(x_{b,0},y_{b,0}),(x_{b,1},y_{b,1}),...,(x_{b,n-1},y_{b,n-1})=p_{b,0},p_{b,1},...,p_{b,n-1}
那么 C ( x ) = p a , 0 p b , 0 , p a , 1 p b , 1 , . . . , p a , n 1 p b , n 1 = p c , 0 , p c , 1 , . . . , p c , n 1 C(x)=p_{a,0}*p_{b,0}, p_{a,1}*p_{b,1},...,p_{a,n-1}*p_{b,n-1}=p_{c,0},p_{c,1},...,p_{c,n-1}
然后再把 C ( x ) C(x) 还原成系数表达式即可。
注意:我们需要保证 x a i , x b i x_{ai},x_{bi} 互不相同)

现在就只用考虑如何实现点值表示和系数表示的互换了。
也就是如何用更少的计算次数来求出 n n 个不同的 x x 值对应的 y y 值。
考虑有两个具有特殊性质的东西:

  1. 单位根
  2. 原根

单位根保证了 w n 0 , w n 1 , . . . , w n n 1 w_n^0,w_n^1,...,w_n^{n-1} 是互不相同的并且有 w n i j = ( w n i ) j w_n^{ij}=(w_n^i)^j
而原根在模数为质数 p p 的时候也有 g 0 , g 1 , g 2 , . . . , g n 1 g^0,g^1,g^2,...,g^{n-1} 是互不相同的并且 g i j ( g i ) j m o d    p g^{ij}\equiv (g^i)^j \mod p
这满足了我们上面的性质,因此我们考虑将 w n 0 , w n 1 , . . . w n n 1 w_n^0,w_n^1,...w_n^{n-1} 作为 x 0 , x 1 , . . . x n 1 x_0,x_1,...x_{n-1} 带入求点值。

然后要用到两个引理:

  1. 折半引理: w n k 2 = w n 2 k w_n^{k*2}=w_{\frac n2}^k (n为偶数 )
  2. 消去引理: w n k = w n k + n 2 w_n^{k}=-w_n^{k+\frac n2}

这两个引理可以画个单位圆简单证明(建议各位神犇自己简要证明一下)
然后利用按照下标的奇偶性来进行分治处理:
f ( x ) = i = 0 n a i x i f(x)=\sum_{i=0}^na_ix^i
=> f ( w n k ) = i = 0 n a i w n i k f(w_n^k)=\sum_{i=0}^na_i w_n^{ik}
=> f ( w n k ) = i = 0 n 2 1 a 2 i w n 2 i k + w n k i = 0 n 2 1 a 2 i + 1 w n 2 i k f(w_n^k)=\sum_{i=0}^{\frac n2-1}a_{2i}w_n^{2ik}+w_n^k\sum_{i=0}^{\frac n2-1}a_{2i+1}w_n^{2ik}
同时又有:
f ( w n k + n 2 ) = i = 0 n 2 1 a 2 i w n 2 i k w n k i = 0 n 2 1 a 2 i + 1 w n 2 i k f(w_n^{k+\frac n2})=\sum_{i=0}^{\frac n2-1}a_{2i}w_n^{2ik}-w_n^k\sum_{i=0}^{\frac n2-1}a_{2i+1}w_n^{2ik}
这一步需要用到引理

所以我们只要算出两个重新分配了系数的多项式的值就可以了。
显然一直分下去只有 l o g log 层。
于是总时间复杂度 O ( n l o g n ) O(nlogn)
注意到递归的时间复杂度很慢,我们可以预处理最后一层的系数的位置然后用迭代的方式还原回去来优化常数

这就成功的实现了系数转点值。

下面来看点值转系数:
在这里插入图片描述
在这里插入图片描述
以上是 f f t fft 的证明, n t t ntt 同理。
一道板题:uoj#34多项式乘法
f f t fft 写法
n t t ntt 写法


fft,ntt做多项式乘法相关题目

cc PRIMEDST 点分治+ f f t fft 优化合并
bzoj4259 f f t fft 套路题
spoj Triple Sums f f t fft +容斥原理
bzoj4827 推式子练习
hdu5829 推式子练习


猜你喜欢

转载自blog.csdn.net/dreaming__ldx/article/details/85372365
今日推荐