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 即可。