我是靠谱客的博主 单薄豌豆,这篇文章主要介绍多项式学习笔记[三](全网最详细!有图有代码有解释有例题有总结!)多项式乘法的一些小Trick例题,现在分享给大家,希望可以做个参考。

文章目录

  • 多项式乘法的一些小Trick
    • 关于差的“卷积”
    • 关于min/max的卷积
  • 例题
    • T1(Luogu P6300)
      • Description
      • Solution
    • T2(Luogu P3338)
      • Description
      • Solution
    • T3(Luogu P3321)
      • Description
      • Solution

多项式乘法的一些小Trick

关于差的“卷积”

众所周知,FFT/NTT 能够快速求出下面的数组 c c c

c i = ∑ j = 0 i a j b i − j c_i=sum_{j=0}^i a_j b_{i-j} ci​=j=0∑i​aj​bi−j​

但是,有的时候,我们要求的却是

c i = ∑ j = 0 n − i a j b i + j c_i=sum_{j=0}^{n-i} a_j b_{i+j} ci​=j=0∑n−i​aj​bi+j​

这显然不是卷积形式了。不慌,我们考虑将 a a a给翻转一下,即

c i = ∑ j = 0 n − i a n + 1 − j b i + j c_i=sum_{j=0}^{n-i} a_{n+1-j} b_{i+j} ci​=j=0∑n−i​an+1−j​bi+j​

由于 ( n + 1 ) − j + ( i + j ) = n + i + 1 (n+1)-j+(i+j)=n+i+1 (n+1)−j+(i+j)=n+i+1与 j j j无关,所以我们只需要将翻转后的 a a a与 b b b求一遍卷积得到 d d d,那么 c i = d n + 1 + i c_i=d_{n+1+i} ci​=dn+1+i​。

关于min/max的卷积

此时我们要求的是 ∑ i = 0 n m i n ( a i , b n − i ) sum_{i=0}^n min(a_i,b_{n-i}) ∑i=0n​min(ai​,bn−i​)(以 m i n min min为例)。

这个式子不能直接用FFT/NTT去求。由于自然数 p p p满足 p = ∑ i = 1 ∞ [ i ≤ p ] p=sum_{i=1}^{∞} [i le p] p=∑i=1∞​[i≤p],从而原式可以化为

∑ j = 1 ∞ ∑ i = 0 n [ j ≤ m i n ( a i , b n − i ) ] sum_{j=1}^{∞} sum_{i=0}^n [j le min(a_i,b_{n-i})] j=1∑∞​i=0∑n​[j≤min(ai​,bn−i​)]

即 ∑ j = 1 ∞ ∑ i = 0 n [ j ≤ a i ] [ j ≤ b n − i ] sum_{j=1}^{∞} sum_{i=0}^n [j le a_i] [j le b_{n-i}] j=1∑∞​i=0∑n​[j≤ai​][j≤bn−i​]

于是我们枚举 j j j,然后令 f i = [ j ≤ a i ] , g i = [ j ≤ b i ] f_i=[j le a_i],g_i=[j le b_i] fi​=[j≤ai​],gi​=[j≤bi​]再累加 f , g f,g f,g的卷积即可。

关于这个东西的应用我们马上就会提到。

例题

T1(Luogu P6300)

Description

给定一个长度为 n n n的序列 A A A和一个数 m m m。对于每个在 [ 1 , m ] [1,m] [1,m]中的数 i i i,你需要分别回答:

⌊ lfloor ⌊ 将 A A A序列中的数两两匹配(可能会有数不在任何匹配中),满足一个匹配中两个数的和恰好等于 i i i的匹配的数量最大值 ⌉ rceil ⌉

n ≤ 1 0 5 ,   a i ≤ 1 0 5 n le 10^5, a_i le 10^5 n≤105, ai​≤105且 m = max ⁡ a i m=max {a_i} m=maxai​。

Solution

令 a a a为 A A A序列的桶,即 a i = ∑ j = 1 n [ A j = i ] a_i=sum_{j=1}^n [A_j=i] ai​=∑j=1n​[Aj​=i]。

不难发现,一次询问的答案即为 ∑ j = 0 n m i n ( a j , b i − j ) sum_{j=0}^n min(a_j,b_{i-j}) ∑j=0n​min(aj​,bi−j​)。这个东西我们在上面提到过,可以先枚举 j j j,然后令 f i = [ j ≤ a i ] , g i = [ j ≤ b i ] f_i=[j le a_i],g_i=[j le b_i] fi​=[j≤ai​],gi​=[j≤bi​]再累加 f , g f,g f,g的卷积得到 a n s ans ans数组。

但是这么做的时间复杂度是 O ( m 2 log ⁡ m ) O(m^2 log m) O(m2logm)。


同时,我们再去考虑一个暴力做法。

我们枚举桶中的两个数 i , j i,j i,j,将 a n s i , j ans_{i,j} ansi,j​加上 m i n ( a i , a j ) min(a_i,a_j) min(ai​,aj​)。

但是这么做的时间复杂度是 O ( m 2 ) O(m^2) O(m2)的。


考虑结合上面两种做法。

令 p p p为使用上述两种做法的分界点。
①根据 a n s = ∑ j = 1 ∞ ∑ i = 0 n [ j ≤ a i ] [ j ≤ b n − i ] ans=sum_{j=1}^{∞} sum_{i=0}^n [j le a_i] [j le b_{n-i}] ans=∑j=1∞​∑i=0n​[j≤ai​][j≤bn−i​],我们只将 j j j从 1 1 1枚举到 p p p,剩下的 j j j我们暂不考虑。
②对于所有满足比 p p p大的 a i a_i ai​去暴力枚举累加贡献。

①的时间复杂度为 O ( p m log ⁡ m ) O(pm log m) O(pmlogm),②的时间复杂度为 O ( ( n p ) 2 ) O((frac n p)^2) O((pn​)2)。为什么②的时间复杂度是 O ( ( n p ) 2 ) O((frac n p)^2) O((pn​)2)呢?因为这里的 a a a是一个桶,若 a i a_i ai​比 p p p大,那么对应的,序列中 i i i出现的次数超过了 p p p。而序列中一共只有 n n n个数,所以满足比 p p p大的 a i a_i ai​的级别只有 O ( n p ) O(frac n p) O(pn​)。

于是总时间复杂度为 O ( p m log ⁡ m + ( n p ) 2 ) O(p m log m+(frac n p)^2) O(pmlogm+(pn​)2)。令 m m m与 n n n同阶,解方程

p n log ⁡ n = ( n p ) 2 p n log n=(frac n p)^2 pnlogn=(pn​)2

解得 p = n log ⁡ n p=sqrt {frac n {log n}} p=lognn​ ​

而由于卷积的复杂度较大,我们取 p = n log ⁡ n 2 p=frac {sqrt {frac n {log n}}} 2 p=2lognn​ ​​时实现是相对最优。

于是时间复杂度为 O ( n log ⁡ n ) O(n log n) O(nlogn)。

T2(Luogu P3338)

Description

在这里插入图片描述

Solution

令 a i = q i , b i = ( 1 i ) 2 a_i=q_i,b_i=(frac 1 i)^2 ai​=qi​,bi​=(i1​)2,则有
E j = ∑ i = 1 j − 1 q i b j − i − ∑ i = j + 1 n q i b i − j E_j=sum_{i=1}^{j-1} q_ib_{j-i}-sum_{i=j+1}^{n} q_i b_{i-j} Ej​=i=1∑j−1​qi​bj−i​−i=j+1∑n​qi​bi−j​

对于右式的前半部分,显然是一个关于“和”的卷积,直接NTT即可;而后半部分是一个关于“差”的卷积,按照本文开头所述的方法,我们需要翻转之后再求一遍卷积。

时间复杂度为 O ( n log ⁡ n ) O(n log n) O(nlogn)。注意精度控制。

T3(Luogu P3321)

Description

在这里插入图片描述

Solution

由于FFT只能处理关于“和”的卷积,所以我们先考虑化加为乘,这样会对问题起到极大的简化作用。

令在模意义下的底数为 b a s e base base。于是,我们就可以将问题转化为: 将给定的序列中的每一个数 a i a_i ai​变成模意义下的 b a s e a i base^{a_i} baseai​,请问能够生成多少个序列,使得这个序列各项之和在模意义下为 log ⁡ b a s e x log_{base} x logbase​x。

现在的问题就十分简单了:处理出原序列的桶,令桶为多项式的各项系数;我们做 ∣ S ∣ |S| ∣S∣次循环卷积,答案即为 x X x^{X} xX( x x x是形式幂级数, X X X为给定的值)项的系数。

我们直接多项式快速幂即可。本题得到完美解决!

正当你代码写完之后,发现……


当 b a s e base base取得不好的时候会出现像哈希冲突一样的玩意儿。比如 m o d = 6 , b a s e = 2 mod=6,base=2 mod=6,base=2时, 2 3 ≡ 2 1 ( m o d   6 ) 2^3 equiv 2^1(mod 6) 23≡21(mod 6);也就是说, 2 2 2既可以表示为 2 2 2也可以表示为 4 4 4,这样导致了答案的不正确。

于是,你得出了以下结论——

⌊ lfloor ⌊ 这个 b a s e base base需要满足 b a s e 1 ⋯ b a s e m o d − 1 base^1 cdots base^{mod-1} base1⋯basemod−1互不相同,也就是说真数 [ 1 , 2 ⋯ m o d − 1 ] [1,2 cdots mod-1] [1,2⋯mod−1]与底数 [ 1 , 2 ⋯ m o d − 1 ] [1,2 cdots mod-1] [1,2⋯mod−1]需一一对应。 ⌉ rceil ⌉

这时恍然大悟的你发现了, b a s e base base事实上就是 m o d mod mod的原根。

于是我们套用原根的板子得到 b a s e base base,然后在模意义下转化数组与限制并多项式快速幂即可。

总时间复杂度为 O ( n + m log ⁡ m ) O(n+m log m) O(n+mlogm)。

最后

以上就是单薄豌豆最近收集整理的关于多项式学习笔记[三](全网最详细!有图有代码有解释有例题有总结!)多项式乘法的一些小Trick例题的全部内容,更多相关多项式学习笔记[三](全网最详细!有图有代码有解释有例题有总结!)多项式乘法内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(242)

评论列表共有 0 条评论

立即
投稿
返回
顶部