6月杂题

还有 50 天左右就 NOI 了,感觉状态比较糟。

1.P7275 计树

做着玩的。题目就是说,只看 \(i,i+1\) 这样的边,每一段长度都要 \(\geq 2\)

先考虑一种容斥:枚举实际上 \((i,i+1)\) 的集合 \(S\) ,再在剩下的 \((i,i+1)\) 中进行容斥,强制选集合 \(T\)

考虑包含 \(S\cup T\) 的树个数,如果现在形成了 \(k\) 段,每段是 \(a_1,...,a_k\) ,则剩下的边方案就是 \(n^{k-2}\prod a_i\)

现在转为枚举 \(a\) 。令 \(f_i\) 表示,把 \(i\) 分成 \(k\) 段,每段 \(\geq 2\)\((-1)^{k-1}\) 之和,则对应方案为 \(n^{k-2} \prod a_if_{a_i}\)

\(f\) 和上述问题都可以多项式求逆解决。

2.ARC134F Flipping Coins

好题。考虑只保留 \(i<p_i\) 的边,则 \(k\) 就是长度为奇数的链的个数,把环按最小值从大到小排成一排,最小值转到最前面,这样构成了另一个排列,它和原排列形成双射。

则现在重定义 \(k\) 为长度为奇数的极长上升子段个数。由于只关心长度的奇偶,我们把每个奇段的末尾位置钦定出来。

也就是说,我们先把序列染成 \(A,B,C\) 三色,\(C\) 代表奇段的末尾,则 \(AB\) 相邻成对地出现。我们要求每个 \(A\) 值小于后面的数 ,\(C\) 大于后面的数。

在没有限制的两个位置间分界,可以把序列分成 \(C..CAB\) 的形式,它的段内方案就是 \(len-1\) 。末尾还有一段 \(C...C\) ,方案为 \(1\)

由此即可多项式求逆解决。

3.P8518 [IOI2021] 分糖果

把修改离线下来,对位置做扫描线,

维护一条折线,\(y_i\) 表示考虑操作 \(1\)\(i\) 且不考虑卡界时,这个盒子的值是多少。

如果只被卡上界,则答案就是 \(c_i-(\max y_i-y_q)\) ,因为 \(\max y_i\) 处一定被卡,且之后一定不会再被卡。

现在有上下界,我们就想知道它到底是被哪个界卡的。考虑找到最大的 \(t\) 使得 \(t\)\(q\) 这一段 \(y\) 的极差 \(\geq c_i\)

那如果 \(y_t\) 是后缀最小值,之后就被且仅被卡上界;否则仅被卡下界。

线段树维护这个过程即可。

4.P6611 [Code+#7]六元环

手玩可以得到,建出大根笛卡尔树后答案等同于取一个大小为 \(4\) 的连通块,但不能取根。

现在要做的就是动态维护笛卡尔树。考虑建立类似于 LCT 的结构:对于每个实链,要么一直向左,要么一直向右。

现在单点加,相当于 \(x\) 要往上单旋。利用 splay 找到所在链上最大的比 \(a_x\) 小的位置,则改变的边的量是 \(O(1)\) 的。此时要么停止上旋,要么 \(x\) 会进入另一条链,继续往上。

实现起来有一些细节,比如说要把这个二叉树和维护的 splay 区分开,还要注意这个题的 LCT 与普通 LCT 的不同。复杂度 \(O(n\log n)\) 。

5.LOJ3074 「2019 集训队互测 Day 3」操作序列计数

显然 \(\le n\) 的答案 和 \(=nk\) 的答案相等。

问题相当于是要让 \(\sum a_ik^i=n-k^L\) ,求 \(a\) 的方案。先把 \(n-k^L\) 转成 \(\sum b_ik^i\) ,其中对于 \(0\le i<L\)\(b_i<k\)

\(a\) 可以通过在 \(b\) 上调整得到。考虑 \(dp_{i,j}\) 为:\(a_{i+1}\)\(a_i\) 贡献了 \(j\) ,填 \(a_0\)\(a_{i-1}\) 的方案数。

\(dp_{i,j}=\sum _{k=0}^{jk+b_i}dp_{i-1,k}\) 。观察可以发现 \(dp_i\) 是关于 \(j\)\(i\) 次多项式。

用点值维护这个多项式,不难做到 \(O(L^3)\) ,其中 \(L\)\(n\) 转成 \(k\) 进制后的位数。

6.P6775 [NOI2020] 制作菜品

考虑 \(m\geq n-1\) 时一定有解:把 \(a\) 从小到大排序, \(a_1\geq k\)\(m\geq n\) ,就直接分出来一段,仍然满足 \(m\geq n-1\)

否则注意到 \(a_1+a_n\geq k\)\(a_1\)\(a_n-k\) 分到一段,此时 \(n,m\) 同时减掉 \(1\)

\(m=n-2\) 怎么做呢。考虑如果取的一段是由 \(u,v\) 组成,建一个无向图,在 \(u,v\) 间连边。令最后每个连通块的权值是:边数-点数。

发现每个权值都 \(\geq -1\) ,而且权值总和是 \(-2\) ,那 \(-2\) 只会由两个 \(-1\) 和若干个 \(0\) 构成。

可得必要条件: \(a\) 能划分成两个集合,使得每个集合满足 \(\sum (a_i-k)=-k\)

由于 \(m=n-1\) 一定有解,所以上面这个条件也是充分的。用 bitset 优化求背包,复杂度 \(O(\frac{n^2k}{w})\)

7.UOJ806 见贤思齐

考虑已知 \(p_i\) 每个时刻的值形成的折线,\(i\) 的折线怎么整出来。 如果一开始 \(a_i<a_{p_i}\) ,就找 \(y=a_i+x,y=a_i\) 这两条线与折线的交点,显然只会交一个地方。

那找到交点 \(X\) 后,对于 \(x>X\)\(f_{i,x}=f_{p_i,X-1}+1\) 。对于前面的部分,有 \(f_{i,x}=a_i+[a_i<a_{p_i}]x\)

再观察一下就能得到一个递推式:\(f_{i,x}=\max(a_i,\min(f_{p_i,x-1}+1,a_i+x))\) 。现在我们要加速对它的求值。

首先这个 +1 不太方便,令 \(g_{i,x}=f_{i,x}-x\) ,则 \(f_{i,x}=\max(a_i-x,\min(f_{p_i,x-1},a_i))\)

维护 \(l=\max(l,a_x-t),r=\max(r,a_x)\) 并一直往上跳,跳到 \(l>r\) 即可算出答案,用倍增实现。

8.ABC304Ex Constrained Topological Sort

如果没有 \(p_u<p_v\) 的限制就是一个贪心问题。

现在我们尝试通过合理的调整 \(l,r\) ,使得在做完贪心后,如果存在 \(p_u>p_v\) 就直接交换,仍然满足 \(l,r\) 的限制。

发现 \(l_v=\max(l_v,l_u+1),r_u=\min(r_u,r_v-1)\) 。这样子交换之后一定合法!这个题就做完了。

9.P6643 [CCO2020] Mountains and Valleys

把直径拎出来后进行分类讨论,通过直径的性质来减少讨论量,很码的一个题。

10.P8351 [SDOI/SXOI2022] 子串统计

建出基本子串结构,按拓扑序对每个块 dp ,转移形如阶梯状路径方案数,分治解决,复杂度 \(O(n\log^2 n)\)

这个题掌握了前置知识后其实很平凡啊!

值得注意的是处理阶梯,把轮廓线记下来比较方便。

11.CF1500F Cupboards Jumps

考虑填完了 \(1\)\(x\) ,目前什么信息对后面是有用的。发现只会关心 \(|a_x-a_{x-1}|\) 的值。

我们把这个值可能是哪些记下来,转移讨论一下,会形如 \(x\) 变成 \(b-x\) ,末尾删掉一个区间,添加一个区间,用 deque 维护。

注意要输出方案,上面的操作很容易可撤销,所以方案也是好找的。

12.CF1098F Ж-function

建反串 sam,求出 fail 树,相当于求 \(\sum\limits_{i=l}^{r} \min(i-l+1,d[lca(p_i,p_r)])\) 的状物。

重链剖分后,把 \(d[lca(p_i,p_r)]\) 拆开处理,在链上算贡献,考虑 \(t_i\)\(p_i\) 这个点到达这条链的深度。

把走到链上的点看成 \((i,t_i)\) ,询问相当于要求 \(\sum \max(\min(b,y,x-l+1)-z,0)[l\le x\le r]\) 这样的东西,可以拆成二维偏序处理,复杂度就是 \(O(n\log^2n)\)

但是我常数太大了,没有过捏。

13.ARC159E Difference Sum Query

观察到题意相当于是给出了一个二叉搜索树,\(X_i\) 表示的是 \(i\) 在这棵树上的深度。

再观察一下,由于 \(\max(\frac{a}{b},\frac{b}{a})\le 2\) ,所以分出来的两个子树大小都 \(\le\frac{2}{3}n\) 。由此,树高是 \(O(\log n)\) 的。

由于 \(i\)\(i+1\) 在这样的树上有祖孙关系,所以 \(|x_i-x_{i+1}|=dist(i,i+1)\) 。那 \(dis(c,d)+\sum\limits_{i=c}^{d-1} dis(i,i+1)\) 其实就是 \(c\)\(d\) 组成的虚树的边数 *2 。

并且这个虚树中 \(<c\)\(>d\) 的点一定在 \(c\)\(d\) 的路径上。我们通过拎出根到 \(c,d\) 的链得到 \(c\)\(d\) 的路径,直接暴力算就好了。

复杂度 \(O(q\log n)\)

14.ABC273Ex Inv(0,1)ving Insert(1,0)n

题意给出了一颗 SBT。我们需要求的就是每个区间的虚树大小之和。

首先考虑整个序列的虚树怎么建出来啊。我们得加速只有一个儿子的情况。也就是快速地往下跳,跳到一个有俩儿子的地方。那这个怎么跳呢。

我们知道,SBT 上的点是由左上的第一个点 \((a,b)\) 和右上的第一个点 \((c,d)\) 。那一步跳到是不可能的。但对于方向相同的,可以加速跳:比如要往右跳,就是找到最小的 \(k\) 使得 \(\frac{a+ck}{b+dk}\geq \frac{x}{y}\) ,然后跳 \(k-1\) 步。

这个复杂度是很对的,因为你考虑一个点走到根,只会改变 \(O(\log n)\) 次方向(就是在辗转相除),所以上面的过程只会跳 \(O(n\log n)\) 次。

建出后枚举一个点,考虑多少个区间使得它存在于虚树中,那这个只跟它子树内编号相邻两个点的间距有关,用启发式合并从下往上做就好了,复杂度 \(O(n\log ^2 n)\)

15.CF1470F Strange Covering

可以发现只有三种情况有效:

case1: 两个矩阵完全不交,直接枚举一个横坐标,切一刀,算两边的点形成的矩形。再在纵坐标做一遍。

case2: 两个矩阵呈十字型。那把所有点形成的矩形求出来后,这两个矩形一定贴着边缘。

预处理出横坐标 \(>r\) 的点的最小/最大纵坐标,\(<l\) 同理。则枚举横坐标 \(l,r\) ,有贡献 \(A(r-l)+B(\max(y'_{r+1},y_{l-1})-\min(x'_{r+1},x_{l-1}))\) 。枚举 \(r\) ,由于 \(x\) 单调不增, \(y\) 单调不减,可以把 \(l\) 分成三段,线段树求最值。

case3: 两个矩阵分别覆盖一个对角。以覆盖左上和右下为例。我们预处理出 \(p_x\) 为横坐标 \(>x\) 的点中纵坐标最小值,\(q_y\) 同理。

则贡献形如 \(xy+(A-p_x)(B-q_y)\) ,并且我们要求 \(p_x\le y,q_y\le x\) ,否则可能有一些点并没有算到,而这部分是在第一类里解决的。

那由于 \(p,q\) 具有单调性,所以枚举 \(x\) ,合法的 \(y\) 形成一段区间,可以线段树上建凸包维护。

复杂度 \(O(n\log^2 n)\) ,空间略卡常。

16. CF1292F Nora's Toy Boxes

先考虑我们会选取怎样的 \(p_x\) 。对于 \(p_x|p_y\) ,我们从 \(x\)\(y\) 连一条边。显然我们只会选入度为 \(0\) 的点。

考虑每个弱连通块,发现我们只会留下一个入度不为 \(0\) 的点。

正难则反,我们看成是从后往前加点。我们称一个入度为 \(0\) 的点被激活,表示它连出的点里有一个被加入了。

第一次可以任意加入一个入度不为 \(0\) 的点,之后加入的需要满足:连向它的点里有一个被激活。

发现只需要记下来哪些点被激活,以及选了多少个点即可,转移是简单的。

而每个联通块入度不为 \(0\) 的点至多 \(\frac{n}{4}\) 个,所以复杂度为 \(O(2^{\frac{n}{4}}n^2)\)

17.LOJ6681 yww 与树上的回文串

我们需要处理所有路径的信息,所以选取点分治解决。

那考虑当前跨过重心的两个点 \(u,v\) ,他们之间怎么得到一个回文串呢?

设根到 \(v\) 的距离更大,则需要满足:根到 \(u\) 形成的串 是 根到 \(v\) 形成的串的后缀,且去掉这个后缀后 根到 \(v\) 为回文串。

那一个思路就是,把重心到所有点的串建出 AC 自动机。

那枚举根到 \(v\) 表示的串在 fail 树上的祖先 \(f\),如果存在一个回文前缀长度为 \(|S_v|-|S_f|\) ,则答案加上 \(val_{f}\)

现在怎么优化呢。需要考察回文前缀的性质:它可能的长度会形成 \(O(\log n)\) 段等差数列!回文前缀能通过维护正反串的哈希值判断。

现在问题可以转化成若干个 \((u,d,x)\) 的询问,在 fail 树上从 \(u\) 到根,有多少个点的长度模 \(d\)\(=x\)

根号分治处理即可,复杂度 \(O(n\sqrt{n}\log n)\)

18.LOJ 6632「EC Final 2018」神秘的……东道主

处理连续段,考虑使用析合树分析。发现这个题其实就是问你长度为 \(n\) 的序列有多少个本质不同的析合树。

注意到析点儿子 \(\geq 4\) ,合点儿子 \(\geq 2\) ,那么设问题生成函数为 \(F(x)\) ,可以写成 \(F(x)=\frac{F(x)^2+F(x)^4}{1-F(x)}+x\)

处理出 \(F^2(x)\)\(F^4(x)\)\(\frac{1}{1-F(x)}\)\(F(x)\) 四个量互相递推即可,复杂度 \(O(n^2)\)

19. CF1089I Interval-Free Permutations/LOJ3397. 「2020-2021 集训队作业」春天,在积雪下结一成形,抽枝发芽

仍然使用析合树,考虑我们想求的答案就是析点的儿子排列的方案。

设答案 \(\geq 4\) 的部分的 OGF 为 \(F(x)\)\(A(x)=\sum x^ii!\)

如果排列建出来的树的根是析点,则对应的 OGF 为 \(F(A(x))\) ,因为每个儿子内部要排列。

如果是合点,假设儿子排列单调递增,则这个排列需要有至少一个 \(x<n\) 使得 \([1,x]\) 值域为 \([1,x]\)

\(f_n\) 为不满足上述条件的方案数,则 \(f_n=n!-\sum f_i(n-i)!\)。设这个 \(f\) 的 OGF 为 \(I(x)\) ,则 \(I(x)=A(x)-I(x)A(x)\) 。答案为 \(A(x)-I(x)=\frac{A^2(x)}{1+A(x)}\)

现在有 \(A(x)=\frac{A^2(x)}{1+A(x)}+F(A(x))+x\) 。即 \(A(x)-\frac{A^2(x)}{1+A(x)}-F(A(x))=x\)

\(H(x)\)\(A(x)\) 的复合逆,有 \(x-\frac{x^2}{1+x}-F(x)=H(x)\) 。怎么求 \(H\) 呢。可以通过求导得到 \(A=x+xA+x^2A'\)

\(H\) 代入 \(x\) ,由 \(A(H(x))=x,A'(H(x))H'(x)=(A(H(x)))'=x'=1\) ,有 \(x=H+Hx+\frac{H^2}{H'}\) ,即 \(H'x=HH'(1+x)+H^2\)

观察 \(x^n\) 系数即可得到答案的递推式,套上分治 NTT 即可做到 \(O(n\log^2n)\)

20.ARC162F Montage

自己想出来个 F 耶。

考虑限制相当于,如果 \(A_{a,b}=A_{c,d}=1\) ,那我们要求 \(A_{a,d}=A_{c,b}=1\) ;如果 \(A_{a,d}=0\)\(A_{c,b}=0\) ,那我们要求 \(A_{a,b}\)\(A_{c,d}\) \(=0\)

先想一下第二种限制,如果存在一个 \((x,y)\)\(0\) 了,那如果以 \(a=x,d=y\) ,则对于 \(i>x,j<y\)\(A_{i,x}\)\(A_{j,y}\) 不同时为 \(1\)

即需要满足: 对于 \(i>x\) \(A_{i,y}\) 全部为 \(0\) ,或者 对于 \(j<y\) \(A_{x,j}\) 全部为 \(0\) 。通过 \(b=x,c=y\) 可以得到类似的限制。

现在如果 \(A_{a,b}\)\(A_{c,b}\) 都是 \(1\)\(A_{i,b}=0(a<i<c)\) 会发生什么。发现 \(i\) 这一列必须都是 \(0\) ,否则不符合前面的限制!

这启发我们把全 0 的行/列删掉来做,可以发现一个矩形插入全 0 的行/列 是不影响正确性的。这样的话,每一行/列的 \(1\) 都是连续的一段!

现在从高往低填每一行,此时再用上第一种限制:若前一行是 \([l0,r0]\) ,这一行是 \([l,r]\) ,则有 \(l\geq l0\)\(r\geq r0\) ;并且 \(l\le r0+1\) ,否则会得到全 0 的列。

为了让每一列有 \(1\) ,我们还要求第一行 \(l=1\) ,最后一行 \(r=m\) ,不难发现这样就能满足所有限制了。

前缀和优化 dp 即可,复杂度 \(O(nm^2)\)

21.P8492 [IOI2022] 无线电信号塔

考虑建出大根笛卡尔树,每个询问对于 \(l\le u \le r\) 找到 \(p_u\) 为往上跳的最后一个 \(a_v<a_u+d\) 的点。则我们需要选择一些 \(p_u\) 使得两两没有祖先关系。

现在对于每个点,看它能不能作为一个被选的 \(p_u\) 。可以发现,我们会取子树内最小的,又由于要尽量往上取,即 \(a_u<\min\limits_{i\in S_u,l\le i\le r} a_i+d\le a_{fa_u}\)

可能的 \(u\) 可以拆成三部分:\(l\)\(r\) 路径上/lca 到根路径上/其它在 \([l,r]\) 间的部分。

第三部分可以主席树算出,即假装 \(l=1,r=n\)\(l\le u\le r\) 中有多少合法。那其它部分就需要在一段直链上修,发现我们只会找出至多一个有用的点,可以倍增找出来。

复杂度 \(O(n\log n)\)

22. LOJ3629 「2021 集训队互测」序列

考虑题目的限制可以转化成,三个数里至多一个 \(\le x\) ,至多一个 \(>x\)

由此我们可以得到若干个形如 \(x_u<a\)\(x_v\geq a\)\(x_u\geq a\)\(x_v<a\) 的限制。

可以用 2SAT 解决,复杂度 \(O(n\log n)\)

23. 多项式多点求值

以前只会多项式除法的那种大常数写法,今天学习了这个好方法。

我们现在要求 \(f(x)=\sum\limits_{i=0}^{n-1} a_ix^i\)\(b_0,b_1,...,b_{m-1}\) 处的值。下面为了方便,假设 \(n=m\)

可以看成是要把 \((a_0,a_1,...,a_{n-1})\) 这个向量乘上一个矩阵 \(A\) 形如 \(A_{i,j}=b_i^j\) 。那这个不好做。

那考虑某个向量乘上 \(A\) 的转置 \(A^T\) 怎么做。现在要算 \(c_i=\sum a_jb_j^i\) ,那这个就很平凡了:

\(c\) 的 OGF 是 \(\sum \frac{a_i}{1-xb_i}\) 。分治算出左右两部分的分子和分母,设为 \(\frac{u}{L},\frac{v}{R}\) ,即可得到 \(\frac{uR+vL}{LR}\) 。最后再做一遍求逆即可。

现在要乘上的是 \(A\) ,就是反着做这个过程,因为上面的步骤可以看成是把 \(A^T\) 拆成 \(B_1B_2...B_m\)\(A\) 就是 \(B_m^T B_{m-1}^T ...B_1^T\)

考虑 \(L,R\) 这些是固定的多项式,我们原来是 \(uR\)\(vL\) 贡献到上面,现在就是上面得到的多项式乘上 \(R\) 贡献给 \(u\) ,乘上 \(L\) 贡献给 \(v\) 。注意这里的"乘"有变化:正常的乘是 \(c_i=\sum a_ib_{j-i}\) ,其中 \(b\) 是常数。那我们倒着来,相当于要算 \(c_i=\sum a_{j+i}b_j\)

24. CF79E Security System

首先考虑,现在有一个序列 \(b\) ,想找一个 \(L\le x\le R\) ,使得 \(f(x)=\sum |b_i-x|\) 最大。那要么 \(x=L,x=R\)

所以在这个问题,我们只需要考虑四个角是否合法。

为了找出字典序最小路径,我们需要 \(O(1)\) 判断,已知当前位置,以及四个角的计数器的值,能否走到终点。

先考虑一些贪心:当 \(x<a\) ,我们会先走到 \(x=a\)\(y<b\) ,我们会先走到 \(y=b\)

这之后左下角的计数器最后的值就固定了,不用管。下面令 \(c:=c-1\)

如果当前有 \(x\geq a+c\)\(y\geq b+c\) ,应该这样贪心:

如果 \(x<a+c\) ,说明 \((a,b+c)\) 的值已经确定,我们就先走到 \(x=a+c\)\(y<b+c\) 同理。\(x\geq a+c,y\geq b+c\) 后,三个角的值都固定了。

现在需要考虑的就是 \((x,y)\) 被包含在矩形内的情况。我们显然要先走到 \((a+c,b+c)\) 再走到终点。发现 \((a+c,b+c)\) 的值是固定的了。

而且 \((a+c,b)\)\((a,b+c)\) 满足:总和是固定的,且第一个数的取值范围是一个区间,区间内的所有数都能调整得到。就很好判了。

25. P5360 [SDOI2019]世界地图

考虑询问的形式,需要我们把前后缀得到的 MST 建出来,然后再调整。

考虑新的边在 \((i,1),(i,m)\) 间,所以对于每个前缀的 MST,求出 \((i,1)\) 这些点在 kruskal 重构树上的虚树。后缀同理。

当然我们只需记下虚树上的点表示的边。

询问就是对 \(3n-2\) 条边跑 kruskal ,得到 \(n-1\) 条要删的边。

现在考虑怎么维护这个前缀呢。事实上,由于第 \(j\) 层新的边只在 \((i,j-1),(i,j)\) 间,我们对于每个前缀,保留 \((1,i),(j,i)\) 这些点形成的虚数即可。

复杂度 \(O((m+q)n\log n)\)

26. LOJ3634. 「2021 集训队互测」音符大师

显然我们只需要记 \((u,x)\) 表示当前一个点在 \(u\) ,一个点在 \(a_i-x(x\le L)\) 。转移就是选其中一个去移动到目标区间里。

我们用线段树维护这个 dp ,在 \(u\) 处记录 \(0\le x\le L\) 的 dp 值。

首先考虑第二种转移,这个是和 \(u\) 无关的,相当于全局乘上一个置换。

再考虑第二种,需要对每个 \(0\le x\le L\) 查询一个前缀的 \(dp-u\) 的最小值,一个后缀的 \(dp+u\) 的最小值,以及一个长度为 \(L\) 区间的所有值。再对一个长度为 \(L\) 的区间逐个进行修改。仍然可以维护。

总复杂度是 \(O(Ln(L+\log n))\) 的。

27.LOJ6680 「hyOI2019」henry_y 的函数

算出 \(g\) 后考虑 \(f\) 的差分数组 \(b\),则 \(b_i=\sum\limits_{d|i} g_d(2\frac{i}{d}-1)\)

线性筛出 \(g\)\(g*I\)\(g*ID\) 即可。

28.LOJ3628. 「2021 集训队互测」树上的孤独

先考虑只有第二棵树怎么做。维护子树内每个颜色的最浅深度,用线段树合并维护,查询就是查前缀和。

当合并时出现两种相同的颜色,需要去重,就要对线段树进行单点修改。而找这个颜色传统的方法也是线段树合并。

现在考虑加入第一棵树,由于只对 \(D1,D2\) 强制在线,我们直接查当前 \(T1\)\(n\) 个点的颜色在 \(P2\) 子树内的信息,每次查就是 \(O(\log n)\) 的。

总复杂度 \(O((m+nq)\log m)\) ,不能通过本题。所以我们要用其他方式来维护颜色的最浅深度以做到单次 \(O(1)\) 查询。

考虑进行重链剖分,用数组记录当前有哪些颜色,以及每种颜色的信息。

先处理重儿子,继承重儿子的数组。再处理轻儿子的信息,注意要新开一层数组。合并是简单的。

层数最多为 \(O(\log m)\) ,复杂度 \(O(m\log m)\)

所以总复杂度就是 \(O(nq+m\log m)\)

29. Baekjoon 19044 Entanglement

考虑从上往下处理每一行,枚举这一行 \(A_i\) 填了什么。那对于 \(C_{i,j}\ne A_i\)\(B_j\) 就确定了。只有 \(C_{i,j}=A_i\) 的没有被确定。

也就是说,虽然我们有很多种取法,但考虑处理到第 \(i\) 行时,每一列只会出现在一种状态里!这样 dfs 下去,一直到 \(i=n+1\)\(B\) 已经确定即可结束。

但需要注意的是,确定 \(B_j\) 后会对一些 \(A_{i_0}(i_0>i)\) 造成影响。那对于每个终止状态,要扫一遍大小为 \((n-i)m\) 的矩阵求出对后面的影响。这样的话就可能被卡到 \(O(n^4)\) 。所以每次确定 \(B_j\) 需要后需要立马更新对 \(A_i\) 的影响。处理这个细节比较多,总之要保证算量是 \(未知列数*n\) 级别的。

复杂度 \(O(n^2m)\)

30. LOJ 3627. 「2021 集训队互测」这是一道集训队胡策题

和上面的题题意一样,但是值域为 \(2\) ,数据范围变大。

首先去掉全 0/1 的行/列,减少讨论量。

怎么去呢,比如有 \(k\) 个全 \(0\) 行,那 \(2^k-1\) 种情况有至少一行 \(A_i=1\) ,此时每一列都有 \(B_j=0\) ,又由于剩下的行至少有一个 \(1\) ,导致所有 \(A_i=1\) 。剩下 \(1\) 种情况就是把它们删掉,递归做下去。

现在,考虑如果钦定一行为 \(A_i=0\) 会发生什么。会导致一些列被确定为 \(B_j=1\) ,这些列又会反过来确定一些 \(A_i=0\) 。如果把被确定的行换到上边,被确定的列换到右边,可以发现矩阵被分成四个部分。

其中左上角一定是全 \(0\) ,右下角一定是全 \(1\) ,否则可以继续确定下去。而且,对于上面的行,它 \(1\) 的个数一定小于等于下面的行,因为每一位要么上面的为 \(0\) ,要么下面的为 \(1\)

所以我们一开始就将矩阵重构,按 \(1\) 的个数从小往大排。

现在再考虑怎么计算一个矩阵的答案,我们找到一处满足左上角全为 \(0\) ,右下角全为 \(1\) 的位置。如果有多处,我们要求先尽量靠上,再尽量靠右。

如果找不到的话,答案显然为 \(2\) :因为任何一次钦定都会导致最后所有 \(A_i=x\) ,所有 \(B_j=1-x\)

如果找到了的话,考虑右上角的子矩阵,根据定义它一定找不到这样的位置。那对于上面的行,如果某个 \(A_i=1\) ,最后一定有所有 \(A_i=1\) ,所有 \(B_j=0\)

再考虑上面所有行为 \(0\) ,就可以得到右边所有列为 \(1\) 。可以递归到左下角的矩阵求方案。

综上,找到了这个位置之后,总方案数是:左下角方案数+1。这个题就 \(O(nm)\) 做完了。

需要注意一些细节:在重构矩阵后,我们递归往下做时,可以发现子矩阵左边/上边全是 \(0\) ,右边/下边全是 \(1\) 。而我们需要算子矩阵某行/列最左的 \(1\) ,最右的 \(0\) ,这个其实就和全局的相等。

复杂度 \(O(nm)\)

31. LOJ3400.「2020-2021 集训队作业」Storm

这个题如果是二分图就可以费用流解决。

需要注意一下这里费用流的复杂度:

考虑我们只会跑 \(k\) 轮 spfa ,而当前有流量的边一定 \(\le 3k\) 。再考虑一条长度为 \(L\) 的增广路,其中至少 \(\frac{L-3}{2}\) 条边都在从右往左走。所以 \(\frac{L-3}{2}\le 3k\)\(L\le 6k+3\)

所以每个点入队列次数 \(\le 6k+4\) ,总复杂度 \(O((n+m)k^2)\)

但现在是一般图,怎么办呢。

考察最优解的形态:如果存在长度 \(=3\) 的链,我们删掉中间的边一定不劣。而且我们一定不会连出环。

所以选的边形成了若干菊花。

有什么用呢?如果我们对整个图黑白染色,使得最优解中每个菊花的中心和其它点颜色不同,即可得到最优解。但我们又不知道最优解,怎么染色呢。

考虑直接随机染色。那假设一个菊花有 \(p\) 条边,它合法的概率就是 \(\frac{1}{2^p}\)。而 \(\sum p\le k\) ,所以一组染色合法的概率 \(\geq \frac{1}{2^k}\)

经过 \(O(2^k)\) 次随机后,随到最优解的概率就非常大了!这个题就做完了,复杂度 \(O(2^k(n+m)k^2)\)

32.UOJ656 【ULR #2】霸占排行榜

一个暴力的想法是建出这个 trie 的 AC 自动机,然后 T 在上面走一遍,每走到一个点权值 +1;再求 fail 树的子树和。注意这里的 AC 自动机因为字符集过大,需要用主席树建。

T 过长,考虑优化。

第一步,我们求出跑完 \(s_{a_1}+s_{a_2}+...s_{a_i}\) 后匹配到的节点;

第二步,现在我们就有若干个 \((u,i)\) 表示从节点 \(u\) 开始跑 \(s_i\) 的事件。就可以把 \(i\) 相同的放在一起处理。

先考虑第一步。我们相当于要求 \(dir_{i,j}\) 表示从 \(i\) 开始匹配 \(s_j\) 后得到的节点。

那匹配到某个位置就需要跳 fail 。设这个要跳的位置是 \(end_{i,j}\) 。此时,如果跳到的串在 \(s_j\) 内,说明 \(i\) 在这个位置后的路径,和 \(1\) 从这个位置开始的路径相同。

否则,考虑跳到的串在 \(s_j\) 外的这段前缀。发现 \(i\) 在这个位置后的路径,和这个前缀从这个位置开始的路径相同。

形式化的,设 \(anc_{i,j}\)\(i\) 在 fail 树上长度为 \(j\) 的祖先,设 \(|x|\)\(u_x\) 的长度。

如果 \(|fail_{end_{i,j}}|\le |end_{i,j}|-|i|\) ,说明 \(dir_{i,j}=dir_{1,j}\)

否则,\(dir_{i,j}=dir_{anc(i,|fail_{end_{i,j}}|-|end_{i,j}|+|i|),j}\)

第二步也能类似的处理,就是从下往上,把从它开始走的路径,经过两次树上差分,变成从它某个祖先开始的路径。

但现在有个问题就是求 \(end_{i,j}\) 。还是对每个 \(j\) 分别考虑。我们想对于一个 \(x\) ,求出哪些点 \(end_{i,j}=x\)

考虑对 \(u_x\)\(s_j\) 为模式串,通过 kmp 匹配到 \(s_j\) 的前缀 \(p\) 。那 \(x\) 能贡献到的 \(i\) ,一定有: \(p\) 存在一个长度为 \(|x|-|i|\) 的 border ,且以 \(x\) 往下的字符中不存在 \(s_{j,|x|-|i|+1}\)

看上去不好处理。但我们发现一个串的 border 能划分成 \(O(\log n)\) 段等差数列,且每一段的后继字符都是相同的。

所以我们直接往上跳这 \(O(\log n)\) 段,如果 \(x\) 往下不存在这个后继字符,那这一段所有 border 都会对某个 \(i\) 贡献,所以这部分复杂度 \(O(L)\);否则,我们看成是覆盖了 \(x\) 的某条边,每条边只会覆盖一次,所以复杂度还是 \(O(L)\)

总复杂度 \(O(ln\log n+(S+l)\log w)\) 。如果最后一部分也用主席树优化,可以做到 \(O(ln\log\log n+(S+l)\log w)\)

33.UOJ682. 【UR #22】月球铁轨

注意到一个关键性质:设 \(f(a,T)\)\(a\)\(T\) 内选一个集合异或上后得到的最大值。\(g(a,T)\) 是同样的过程得到的最小值。

有性质: \(f(a,T)\oplus g(b,T)=f(a\oplus b,T)\)

考虑这个题想让我们求什么。设 \(s_i\)\(a_1\)\(a_i\) 的异或和,\(T(i,j)\)\(a_i\oplus b_i\)\(a_j\oplus b_j\) 的线性基。

则我们想求 \(f(s_{i-1}\oplus s_j,T(i,j))=g(s_{i-1},T(i,j))\oplus f(s_j,T(i,j))\) 的第 \(K\) 小值。

考虑对 \(T(i,j)\) 大小相同的段同时处理。则此时 \(g(s_{i-1},*)\)\(f(s_j,*)\) 都是固定的。相当于有每个左端点有权值 \(a_i\) ,右端点有权值 \(b_j\) 。每个 \(j\) 有左端点范围 \(L_j\le i\le R_j\)

此时考虑从高到低逐位确定答案。对每个大小用 可持久化 01trie 计算这一位取到 \(0\) 的子段个数。可以发现我们只需要保留当前层 trie 的信息,所以空间复杂度 \(O(nm)\) ,时间 \(O(nm^2)\)

34.CF1842H Tenzing and Random Real Numbers

如果限制形如 \(a_i\le a_j\) 那这个题是不是很好做啊。

现在考虑,形如 \(a_i+a_j\le 1\) 怎么转化过来。考虑如果 \(|a_i-0.5|\le |a_j-0.5|\) ,那要求 \(a_j\le 0.5\) 即可。

同理,\(a_i+a_j\geq 1\)\(|a_i-0.5|\le |a_j-0.5|\) ,则要求 \(a_j\geq 0.5\)

按照 \(b_i=|a_i-0.5|\) 从小往大状压 dp 即可。

posted @ 2023-06-02 19:29  grass8woc  阅读(428)  评论(2编辑  收藏  举报