2022.7.19 闲话

约定:

  • \(f^k(x)=(f(x))^k\) .
  • \(L\) 是值域 .

2-SUM Counting

给一个序列 \(\{a_n\}\) 和一个正整数 \(k\),问有多少对 \((i,j)\)\(1\le i,j\le n\))使得 \(a_i+a_j=k\),对 \(998244353\) 取模 .

Algorithm 1 \(O(n^2)\) 暴力 .

Algorithm 2 开一个桶,算出 \(\displaystyle t_k=\sum_{i=1}^n[a_i=k]\),于是答案是

\[f(k)=\sum_{i+j=k}t_it_j \]

注意到是卷积形式,可以 NTT \(O(L\log L)\) 解决 .

Algorithm 3 开一个 Hash Table,把所有 \(a_i\) 存进去,扫一遍在 Hash Table 里查询 \(k-a_i\) 即可,最优 \(O(L)\) .


2-SUM Finding

给一个序列 \(\{a_n\}\) 和一个正整数 \(k\),找一对 \((i,j)\) 使得 \(a_i+a_j=k\) .

Algorithm 1 \(O(n^2)\) 暴力 .

Algorithm 2 开一个 Hash Table,把所有 \(a_i\) 存进去,扫一遍在 Hash Table 里查询 \(k-a_i\) 即可,最优 \(O(L)\) .

更高的 SUM 问题仍可以 Hash Table 解决 .


3-SUM Multi-Counting

给一个序列 \(\{a_n\}\),对于每个 \(s\in[1,m]\),问有多少对 \((i,j,k)\)\(1\le i,j,k\le n\))使得 \(a_i+a_j+a_k=s\),对 \(998244353\) 取模 .

\(\displaystyle t_k=\sum_{i=1}^n[a_i=k]\),于是答案是

\[f(s)=\sum_{i+j+k=s}t_it_jt_k \]

三元卷积非常牛逼哈,但是我们仔细观察就可以发现这个是可以拆成两次普通卷积的 .

多组询问非常平凡,具体的,令 \(\displaystyle F(z)=\sum_{k\ge 0}z^kt_k\),则对于一个 \(s\),答案为 \([z^s]F^3(z)\) .

两次 NTT,\(O(L\log L)\) .

更高的 SUM Counting 也可以这么解决 .


2D - 2-SUM Multi-Counting (Weak)

给两个序列 \(\{a_n\},\{b_n\}\),多组询问,每次给一个 \(x\),问有多少对 \((i,j)\)\(1\le i,j\le n\))使得 \(a_i+a_j=b_i+b_j=x\),对 \(998244353\) 取模 .

开一个 Hash Table,每次存一个 pair \((a_i,b_i)\) .

在值域上枚举 \(x\),在 Hash Table 里查 \((x-a_i,x-b_i)\) 即可 .

时间复杂度最优 \(O(L)\) .


2D - 2-SUM Multi-Counting

给两个序列 \(\{a_n\},\{b_n\}\),多组询问,每次给一对 \(x,y\),问有多少对 \((i,j)\)\(1\le i,j\le n\))使得 \(a_i+a_j=x\)\(b_i+b_j=y\),对 \(998244353\) 取模 .

严格强于今天模拟赛 T3(Common).

做法也是卷积,大概有两种 .

Algorithm 1

考虑把两个数压成一个数 .

首先定义 \(\operatorname{encode}(a, b) = L\cdot a + b\)\(L\) 比值域大一点 .

\(\displaystyle t_k=\sum_{i=1}^n[\operatorname{encode}(a_i, b_j)=k]\),构造多项式:

\[F(z)=\sum_{k\ge 0}z^kt_k \]

于是 \([x^{\operatorname{encode}(x, y)}]F^2(z)\) 即为答案,\(O(L^2\log L)\) NTT 即可 .

Algorithm 2

\(\displaystyle r_k=\sum_{i=1}^n[a_i=k], t_k=\sum_{i=1}^n[b_i=k]\) .

于是构造二元多项式:

\[\begin{aligned}F(z_1, z_2)&=\sum_{k_1\ge 0}\sum_{k_2\ge 0}z_1^{k_1}z_2^{k_2}r_{k_1}t_{k_2}\\&=\sum_{k_1\ge 0}z_1^{k_1}r_{k_1}\sum_{k_2\ge 0}z_2^{k_2}t_{k_2}\end{aligned} \]

考察其卷积,可以发现两维分别卷积了 .

于是答案就是 \([z_1^x,z_2^y]F^2(z_1,z_2)\)(我也不知道这个二元的提取系数是不是这么写)

于是上一个 2D 的 NTT(具体的,先对每列做 DFT,再对每行做 DFT,然后点乘,然后对每行做 IDFT,最后对每列做 IDFT),就可以维护出 \(F^2\) 了 .

类似的可以扩展到 \(k\)D .

这样:\(a\)D - \(b\)-SUM (Multi-)Counting 被解决 .


Finding 大概都可以 Hash 吧,口胡的没仔细想……

posted @ 2022-07-19 19:50  Jijidawang  阅读(123)  评论(0编辑  收藏  举报
😅​