Last Dance

Solution Set #11

2025.10.21 开始。

769. qoj10156(状压)

\(r,c\leq 4\) 是 [SD 集训 2025 Round1] D1T1,这个题保证了 \(r|n,c|m\) 所以可以做到更好。

这个限制是相对比较强的,差分一下有 \(a_{i+r,j+c}=a_{i+r,j}+a_{i,j+c}-a_{i,j}\)。进而如果左上角的倒 L 形确定后至多有一组解,再推一下,结论是每个\(\bmod r,\bmod c\) 的等价类要么行全相等,要么列全相等。容斥一下,枚举集合 \(S\) 钦定是全相等的,\(S_1\cap S=\varnothing\) 是行全相等的,大概有 \(\mathcal O(3^{rc}(r+c))\) 的做法。

事实上并不需要进行容斥,直接做就好。将全相等和行相等进行合并,记为 \(A\) 类,否则令列相等但不全相等为 \(B\) 类。暴力枚举等价类的 \(A,B\) 情况,是可以计算的。这样复杂度 \(\mathcal O(2^{rc}(r+c))\)。具体地,计算过程中向下和向右拓展是独立的。假设对于 \(A\)\(x\) 个,那么对应的方案数为 \(f_x=\sum_{y=0}^x\binom{x}{y}^{\frac{m}{c}}\)\(B\)\(x\) 个,这一部分和 \(f\) 类似,但是要容斥减去某些格子全都相同的结果,记作 \(g_x\)。记每行的 \(A\) 个数为 \(r_i\),每列 \(B\) 个数为 \(c_i\),那么答案为 \(\prod f(r_i)\prod g(c_i)\)

注意到本题性质保证了行,列间是没有任何区别的。按照行转移,记录当前的 \(\{c_i\}\),每次枚举当前行状态,这样考虑列个数对应的多重集,状态数是 \(\binom{r+c}{r}\) 级别,再乘以 \(r2^c\) 就可以通过。时间复杂度 \(\mathcal O(\binom{r+c}{c}r2^c)\)。也可以按格转移,复杂度 \(\mathcal O((r+1)^c\text{poly}(rc))\)

770. qoj14312(dp,线段树)

第一大难点是状态设计。对于时间维是很难做 dp 的,因此一定是对序列前缀做 dp,同时考虑一下时间的影响。对于是否被操作覆盖进行分类,那么不被操作的形成若干断点,考虑以此作为关键点转移,满足关键点之间都是被覆盖的。令 \(f_i\) 表示对 \([1,i]\) 考虑保证 \(i\) 不被覆盖的最大贡献,转移形如枚举 \(w(l,i-1)\) 以及 \(f_{i-1}\to f_i\)。前者是不好算的,但是可以将状态放在操作上。即令 \(g_i\) 表示 \(r_i\) 最终由操作 \(i\) 贡献,保证 \(r_i+1\) 暂时不被覆盖,在 \([1,r_i]\) 产生的最大贡献,此时 \(f_{i-1}\to f_i\),以及枚举 \(r_j=i-1\) 执行 \(g_j\to f_i\)

此时特殊性质会起作用,注意到发生包含关系只会有后面包含前面,此时前面完全没有用,因此最终的区间集是互不包含的。考虑 \([l_i,r_i]\) 在时间 \(i\) 后面的操作 \([l_j,r_j]\),被考虑一定有 \(r_j<r_i\),直接从 \(g_j\) 转移。你发现状态少了,还要加一个 \(h_{i,j}\) 表示 \(i\) 操作有效的范围是 \([j,r_i]\),此时从 \(j<i,k<l_i\leq r_j\) 的状态 \(h_{j,k}\) 进行转移,而 \(j>i\) 会从 \(g_j\) 转移到 \(h_{i,r_j+1}\)。通过 \(j>i\) 转移到一个 \(h\) 上后,只需要考虑 \(i\) 贡献到一个 \(k>i\) 上,此时有 \(r_j<l_k\),通过 \(i\) 来连接。由于 \(i\) 只有连接作用,所以对于一个 \(g_j\),找到覆盖 \(j\)\(i<j\) 的线段中的三种颜色,使得 \(r_i\) 最大。转移枚举一下前三大,扫描线做一下就好了。然后再用数据结构,维护一下 \(j<i\)\([l_j,r_j]\) 完整生效的转移。

\(n,m\) 同阶,时间复杂度 \(\mathcal O(n\log n)\)

771. qoj12019(扫描线)

处理每个位置的前驱后继 \(pre,nxt\),判定条件为 \(\min_{x=j+1\sim k}pre_x\ge i,\max_{x=i\sim j}nxt_x\leq k\)。固定 \(i,k\) 合法的 \(j\) 是一段区间,固定 \(j,k\) 合法的 \(i\) 是一段区间。考虑扫描线 \(k\),维护所有 \((i,j)\) 的信息。对于 \(j\)\(i\) 的上界是 \(R_j=\min_{x=j+1\sim k}pre_x\),显然具有单调性,下界是前面首个 \(nxt_i>k\) 的位置 \(+1\),记为 \(L_j\),则折线 \(L\) 同样具有单调性。

维护 \(R\) 对应的折线,每次会推平一段后缀,在单调折线 \(L\) 上二分一下,撤销掉以前的贡献;考虑 \(nxt_i>k\) 的位置是黑点,那么每次移动会把 \(pre_i\) 变为白点,后面一个连续段会往下掉。查一下和 \(R\) 的交点。使用线段树做这些操作,时间复杂度 \(\mathcal O(n\log n)\)

772. THUSC2023 D1T2(图论,dp)

link。显然相邻两次回到 \(0\) 中间一定会完成若干个表演,所以最终一定是根据 \(0\) 来划分,转移要求出 \(f_{l,r}\) 表示 \(0\to l\to \cdots\to r\to 0\),中间不回到 \(0\),最后做 1D-1D 的 dp 求出答案即可,这里能量的限制就没有了。

使用 floyd 处理两点间最短路,一个重要的量是求出走到一个点后的剩余时间。注意走到一个补充点后剩余时间会立刻回到 \(L\),以此为关键状态划分。在补充点之间转移,枚举最开始的 \(0\) 走的 \(L\),设 \(dp_{u,i}\) 表示 \(r=i\),当前在补充点 \(u\) 的最小时间。转移枚举 \((v,j)\)。结合外层枚举 \(L\),总时间复杂度 \(\mathcal O(n^3m^2)\)

注意到 \(u,v\) 之间 \(dp_{u,l}\) 可以转移的范围是一维偏序。对 \(r\) 做扫描线,尝试整体转移来去掉 \(l\) 的枚举。对于每个 \(u\),维护 \(f_{u,l}\) 向后的决策,每次 \(r\to r+1\) 会让所有代价都加上 \(dis_{r,r+1}\)。每次把这一轮的 dp 值都求出来,然后同一个 \(r\) 内部做一下最短路(不加堆优化的 dijkstra)。维护一下每个 \(u\) 向后的贡献即可。时间复杂度 \(\mathcal O(n^2m^2+n^2m\log nm)\)

773. 20251022 模拟赛

C. qoj9482(扫描线,异或哈希)

Solution 1:每对数造成的限制是两个矩形加,现在要查子矩形中 \(1\) 的个数。注意到只统计 \(l,r\) 同奇偶的点至少权值为 \(1\),这样维护最小值和最小值个数即可。扫描线做即可,时间复杂度 \(\mathcal O(n\log n)\)

Solution 2:不妨设这个 \(a_i\) 是在左边出现的。对 \(r\) 扫描线,维护所有 \(l\) 的贡献。若 \(r\) 并非首次出现,那么删掉备选集合中 \(>pre_r\)\(l\)。考虑所有前缀只出现的一次的染黑,只有最后一个黑点能收到贡献,值为到倒数第二个黑点中 \(l\) 的个数。直接用 BIT 来查询个数,用栈来维护当前所有 \(l\),以及 std::set 维护所有黑点,时间复杂度 \(\mathcal O(n\log n)\)

Solution 3:考虑异或哈希,在 Solution 2 的基础上,枚举 \(r\) 后用 hashtable 查询 \(sum_{l-1}=sum_r\oplus h_{a_p}\) 的个数即可。时间复杂度 \(\mathcal O(n)\)

D. qoj8003(图同构,二分图匹配)

考虑 dp,为 \(T_1\) 任意定根,求 \(f_{u,(v,x)}\) 表示 \(T_1\)\(u\) 子树是否可以与 \(T_2\)\((v,x)\) 断开后的 \(v\) 子树进行匹配。统计答案枚举两侧的根匹配,对于 \(u\) 的所有儿子和 \(v\) 的出边跑二分图匹配。转移形如对子树跑一遍然后合并时判是否存在二分图完美匹配,但是太慢了。

在第一棵树上 dfs,从下往上考虑每个点匹配的情况。将匹配与求 \(f\) 的过程同时进行,若当前是以 \(T_2\) 的点 \(r\) 为根,求出其与 \(T_1\)\(u\) 所有儿子的匹配后,已经有完美匹配那么答案就是 Yes 了。否则如果此时最大匹配 \(<|R|-1\) 时一定无论如何都不存在最大匹配,所有 \(f_{u,r,v\in nxt(r)}=0\);否则找到并非是最大匹配的必经点,就有 \(f_{u,(r,v)}=1\),可以在 dinic 过程结束后同时求出。优化在于你这里不是枚举断开的边而是直接枚举那个 \(T_2\) 上的根(即断开的边指向的点),所以可以接受。时间复杂度 \(\mathcal O(nm\sqrt m)\)

可以分析到 \(\mathcal O(nm^{5/4})\)

774. *qoj12020(颜色段均摊,单侧递归)

考虑 \(1\) 操作为全局操作时,记当前操作了 \(k\) 次,那么只需要查询 \(\max(a_{l\sim l+k}),a_{l+k+1},\cdots,a_{r+k}\) 的前缀 \(\max\) 之和。预处理 \(nxt_i\) 表示下一个 \(a_j>a_i\),形成一棵树 \(i\to nxt_i\),从 \(l'\) 位置开始向上跳,容易倍增回答询问,复杂度 \(\mathcal O((n+q)\log n)\)

注意到任意时刻的 \(a\) 真实值可以表示为 \(\max(a_{i\sim b_i})\),发现 \(b\) 具有单调性,每次相当于令 \([l+1,r]\) 向左移位,并保持原有 \(r\)用颜色段的角度刻画数列,令 \(c_i=\max(a_{b_{i-1}-1+1\sim b_i})\),结论是令初始值 \(x=\max(a_{l\sim b_l})\),此时做的是在 \(c_{l\sim r}\) 上求以 \(x\) 为初值的前缀 \(\max\) 信息。注意到 \(c\)\(a\) 的子序列,每次删除一个 \(l\) 并更新 \(l+1\),在平衡树上做类似单侧递归的事情,时间复杂度 \(\mathcal O((n+q)\log^2n)\)。但是没必要,结论是这个压根不改变 \(nxt\) 树的结构,因此直接 BIT 维护单点修改以及链查询,询问时差分成两段到根链即可。时间复杂度 \(\mathcal O((n+q)\log n)\)

775. qoj12023(最优解集调整,线段树)

问题等价于最大化使用的优惠券个数,将 \(a_i\) 拆为 \(b_i=a_i\bmod c\)\(d_i=\frac{a_i-a_i\bmod c}{c}\)。如果在某个位置使用 \([0,b_i]\) 张优惠券就不影响获得的个数,这是优秀的,否则后续每 \(c\) 张中第一张会让获得的个数 \(-1\)。显然 \(b_i\) 部分会被尽量使用,否则延后贡献,当前不被使用。可以暂时认为后面每次都是整个 \(c\) 地去使用,如果前面多了后面少了,向后调整一下不劣。因此只考虑 \(d_i\) 的贡献时,一定是前缀都是 \(0\),后缀都取满,中间可能不取满。这样贡献形态就容易刻画:前缀 \([1,x-1]\) 贪心地在 \([0,b_i]\) 中减最多,后缀 \([x+1,n]\) 每个都是用干净优惠券,\(x\) 满足前述条件时尽量多取。

枚举 \(x\) 容易得到 \(\mathcal O(nq)\) 做法。令不考虑 \(d_pc\) 贡献前的剩余优惠券个数为 \(rem_p\),显然 \(x\) 满足 \(rem_x\in[suf_x,suf_x+d_xc)\)。判定的 \(x\) 是一段后缀,猜测直接取合法后缀中的首个元素作为最终确定的 \(x\) 就是最优的,也就是说当 \(x\sim n\) 无法全部用优惠券时会选 \(x\),此时要求 \(x+1\sim n\) 可以全部用优惠券。因此这样的 \(x\) 是唯一的。使用线段树维护信息,查询时在上面二分,时间复杂度 \(\mathcal O((n+q)\log n)\)

776. qoj12024(实数随机,计数)

\(x_i\) 的整数和小数分离,则有 \(x_i=y_i+z_i,y_i\in[0,m-1]\cap \Z\),而我们只关心 \(z_i\) 相对大小关系,因此 \(z_i\) 的排名可以看为 \(n!\) 个排列 \(p\) 中随的一种。因此限制 \(x_i>x_{i-2}+k\) 可以转化为要么 \(y_i>y_{i-2}+k\) 要么 \(y_i=y_{i-2}+k\wedge p_i>p_{i-2}\)

容易有一个 dp 是记录最后两项在前缀的相对排名,以及 \(y\) 真实值。使用前缀和优化可以做到 \(\mathcal O(n^3m^2)\) 的复杂度。注意到记录 \(y_i\) 后,\(y_{i-1}\) 只需要保留到 \(y_i-k-1\)。注意到有解的限制是 \(nk=\mathcal O(m)\),因此前述状态为 \(\mathcal O(n^3km)=\mathcal O(n^2m^2)\)。前缀和优化后复杂度与状态数相同。

777. qoj7766(dp)

\(k\) 越小,最终可以得到的 \(f(p)\) 字典序越小。\(q=1\sim n\) 时,考虑有多少个 \(i\) 使得 \(\max p_{1\sim i}=i\),只需要让这类个数 \(\ge k\) 即可。直接 dp。设 \(F_n\) 表示 \(n\) 阶排列使得前面恰好只有 \(i=n\) 成立的个数,递推时可以用这个来容斥,复杂度 \(\mathcal O(n^3)\)

首位一定是 \(\min a_{1\sim n-k+1}\),注意到 \([1,n-k+1],[n-k+2,n-k+2],\cdots,[n,n]\) 提供了前 \(n-k+1\) 位的上界。考虑 \([1,n-k+1]\) 什么时候能缩掉(并非最优):从 \(\min\) 开始从小往大考虑段 \([1,n-k+1]\) 中的元素,找到最小的时刻使得它们构成了一段完整前缀,此时缩到这一步一定更优。如果 \(pos=n-k+1\),那么后面只能是若干单点;如果 \(pos<n-k+1\),下一步可以考虑入 \(\min\) 的元素添加了 \(p_{n-k+2}\),如果它比 \(q_{pos}\) 要小,说明下一步必须选这个点提到最前面,后面形成若干单点;否则向后正常做。

\(q\) 的角度,找到首个 \(q_i>q_{i+1}\) 的位置 \(t\),就说明某一步取的 \(pos=t\) 后,下一步添加的单点恰好是 \(q_{t+1}\) 的值。进一步你枚举这段是 \(q_{t+1\sim R}\),显然有 \(R>t+1\) 时要求 \(q_{t+2}>q_t\),且这一段内部单调。在 \([1,t]\) 划分的段数容易计算,用 subtask 的做法求。\([t+1,R-1]\) 任意排列,\([R+1,n]\) 都是单点因此固定。 总时间复杂度 \(\mathcal O(n^3)\)

778. qoj4901(树上问题,博弈,点分治)

在原树存在的额外边显然无效。找一些显然必胜的终止态,发现 \(a\) 是某条树上距离 \(>2\) 条边的额外边的端点时,\(b\) 无论在哪都是必胜的,称这样的 \(a\)必胜点。结论是 \(a\) 获胜当且仅当走到了一个必胜点上,否则仅考虑 \(=2\) 距离的额外边,要追到时是无法离开 \(b\) 的邻域的。这样只需要判定是否可以在 \(b\) 不碰它的前提下走到一个必胜点

树上此时只剩下距离为 \(2\) 的额外边。注意到 \(a\) 最终可达的是断开 \(a\to b\) 路径上一条边所形成的连通块,取出路径 \(p_1=a\to p_2\to\cdots\to p_k=b\),那么走到 \(p_t\) 时,令 \(a\) 走过来需要 \(t_1\) 的时间,限制为 \(b\) 走到 \(p_{t}\) 需要的时间 \(>t_1\),或者 \(p_t\) 跳到一个 \(p_{t+1}\) 的儿子上。找到一个最小的 \(t\) 使得断开该边后 \(a\) 的连通块内有黑点,再套用前述条件判定即可。\(t_1\) 是有单调性的,因此走到最小的 \(t\) 是不劣的。可以 \(\mathcal O(\log n)\) 判定一组 \((a,b)\) 是否合法。

拓展一下,考虑点分治,计算经过 \(rt\) 的合法 \((a,b)\) 个数。先设 \(a\ne rt,b\ne rt\),否则可以分别单独拿出来对每个 \(b/a\) 做。讨论这个最小的 \(t\) 在哪里,如果在 \(a\to rt\)(不含 \(rt\))的路径上,限制只剩下 \(col_a\ne col_b,\text{dist}(b,u)>lim\),这是点分治容易算的,整体做二维数点后容斥掉 \(col_a=col_b\) 的。否则在 \(rt\to b\)(含 \(rt\))的路径上,这里就和 \(b\) 关系更大。去除掉前述能在 \(a\to rt\) 路径上找到 \(t\)\(a\)。此时可以找到路径上最浅的 \(t\),贡献与前面相似。注意你需要讨论:\(t\) 是否是 \(rt\),如果不是就需要讨论,\(a\) 走到的是通过额外边来到 \(top_b\) 还是到的 \(rt\)

时间复杂度 \(\mathcal O(n\log^2n)\)

779. 20251023 模拟赛 D(博弈 dp,结论推导)

对于局面给定时,进行倒序 dp。直接设 \(f_{i,0/1}\) 表示游戏进行到第 \(i\) 轮,在进行操作前第 \(i\) 个位置是否被翻转,从现在开始到结束先手的收益减去后手的收益的最大值,这里考虑的是 \([i,n]\)。初始值有 \(f_{n,0}=a_n,f_{n,1}=-a_n\),最终 \(f_{1,0}\) 表示的就是最终先手与后手的收益之差,根据所有位置的价值之和即可算出答案。对于 \(1\leq i<n\) 的转移有 \(\max(a_i-f_{i+1,0},a_i-f_{i+1,1})\to f_{i,0},\max(a_i-f_{i+1,0},-a_i-f_{i+1,1})\to f_{i,1}\)。没法矩阵乘法,考虑化简。

注意到两者的差别仅在于 \(-a_i-f_{i+1,1}\)。而 \(a_i\) 任意时刻非负,那么就必然有 \(f_{i,0}\ge f_{i,1}\)。直接设 \(g_i=f_{i,0}-f_{i,1}\),重新定义 \(f_i\) 代表原来的 \(f_{i,0}\),不难发现此时 \(g_n=2a_n,f_n=a_n\),转移为 \(f_i=g_{i+1}-f_{i+1}+a_i,g_i=\min(2a_i,g_{i+1})\)。整理可得:\(ans=f_1=\sum_{i=2}^n(-1)^ig_i+\sum (-1)^{i+1}a_i\)。而 \(g_i\) 就是 \([i,n]\)\(2a_i\) 的后缀 \(\min\),只需要维护这个式子的结果作为最终答案。

带修是容易的。在线可以直接使用楼房重建线段树做到 \(\mathcal O(n\log^2n)\),离线可以换维扫描线,segbeats 套历史和即可 \(\mathcal O(n\log n)\)

780. JOISC2016 选做

D1T3. *loj2731(计数,dp)

有解的充分必要条件是:\(1,3\) 行不存在连续两个 \(0\),且四个角均为 \(1\)。也就是说对于 \(1,3\) 行,一个 \(0\) 的两侧必然都是 \(1\)。注意到第二行初始的 \(1\) 会将两侧完全分割成两个独立的子问题,因此按第二行的 \(1\) 划分出 \(0\) 的极长连续段,每个段独立,最后容易合并。注意如果 \(1\) 上下的位置是 \(0\),则两侧必然是 \(1\),这个 \(0\) 可以插入到任意位置。每个子问题为第 \([l,r]\) 列,其中 \(A_{2,l\sim r}\) 均为 \(0\),可以认为 \(l-1,r+1\) 列均为 \(1\)

考虑直接对前缀状态设计 dp,发现如果一个 \(a_{2,i}\) 钦定了是两侧更早加入导致他能加入,那么会对后面造成影响,因此要放进状态中。尝试记录前缀所有点的相对顺序,则 \(1/3\) 行的点相互之间没有限制。最终状态是 \(f_{i,j,0/1}\) 表示考虑到 \(i\),前缀相对顺序中 \(p_i=j\)\(i\) 是依靠左右还是上下加入。注意如果是左右,那么加入时上下至少有一个空的。转移时前缀和优化,时间复杂度 \(\mathcal O(n^2)\)

D3T2. P2075 / loj2736(分块)

\(\text{LIS}\) 有一种贪心的方法:依次处理 \(a_1,a_2,\cdots,a_n\),每次在一个集合中加入 \(a_i\),然后删除一个大于 \(a_i\) 的最小元素(如果没有不删除),最后集合的大小就是 \(\text{LIS}\) 长度。定义一个区间 \([l,r]\) 按这个操作执行的集合的结果为 \(S_{l,r}\)。归纳可证 \(S_{l,r},S_{l+1,r}\) 差至多为 \(1\) 的子序列,且 \(S_{l+1,r}\subseteq S_{l,r}\)。于是我们定义 \(cnt_x\) 为元素 \(x\)\(S_{*,m}\) 中出现次数,即最大的 \(l\) 使得 \(x\in S_{l,r}\)。注意查询时只需要关心 \(cnt_x\) 组成的可重集。

\(m\) 变成 \(m+1\) 时,设当前加入的数为 \(x\),考虑加入后改变的 \(cnt_x\)\(p_0=x,p_1,p_2,\cdots,p_k\),需要满足 \(p_i < p_{i+1}\)\(cnt_{p_i} < cnt_ {p_{i+1}}\),在此基础上 \(p_i\) 最小。新的 \(cnt'_{p_{i+1}}=cnt_{p_i}\)\(cnt'_{x}=m+1\))。即:维护一个变量 \(now=0\),初始 \(cnt_{a_{m+1}}=m+1\),从 \(i=a_{m+1}+1\to n\),若 \(cnt_i>now\) 则交换 \(now,cnt_i\) 的值。此时 \(cnt_x\) 组成的可重集的修改量是 \(\mathcal O(1)\) 的,找到这个元素并修改即可。

这个操作是 loj2736。考虑分块,注意经过一个整块操作后的值一定是 \(\max(now,\max a_i)\)。这里经过一个整块时,整块内部的顺序就不重要,只关心可重集。逐个整块考虑,维护进入整块前的 \(now\),如果 \(now>\max a_i\) 那么跳过;否则要将 \(\max\) 弹出作为新的 \(now\),使用 priority_queue 维护每个整块的可重集即可,并将操作前的 \(now\) 加入这个整块的【标记集合】以待重构。

现在需要支持 pushdown 来重构整块。维护操作序列 \(x\),令原先序列为 \(b\)。如果 \(b_1<\min(x)\) 那么无事发生,否则变为 \(\min x\),这个 \(\min x\) 对后续的影响是变为 \(b_1\)。直接用一个小根堆 \(Q\) 维护操作序列 \(x\),相当于每次向 \(Q\) 中插入 \(b_i\),令 \(b_i'\)\(Q\) 的堆顶并弹出。

时间复杂度 \(\mathcal O(n\sqrt n\log n+q)\),因为这里可以对 \(cnt\) 的修改使用分块平衡。

D4T3. loj2740(Hall 定理,线段树)

写成左右各 \(n\) 个点的二分图,每个点有颜色,记每个左部点向右侧最后 \(t_i\) 个点连边,那么要最大化完美匹配中同色的边数。左部点从后往前扫,能匹配的范围单调扩张,此时扫到 \(u\) 就一定是尝试匹配合法范围中第一个与其同色的(否则调整掉不劣),使用 Hall 定理维护所有前缀信息来检测加入这一对匹配后剩余点是否仍能合法。线段树维护,时间复杂度 \(\mathcal O(n\log n)\)

781. ARC114F(字典序,贪心)

\(p_1\leq k\) 时平凡,分割点一定是 \(1\sim k\)。否则首位一定是 \(p_1\)。注意到,划分方式重排只会关心首位的大小。

\(1\) 最终所在段为 \([1,l]\),那么 \(a'_{l+1}\ge a_{l+1}\)。因此现在先最大化 \(\text{lcp}\)。二分 \(mid\),令最终 \(\text{lcp}(a',a)\ge mid\)。前缀的划分点是以 \(1\) 开头的递降子序列,假设选了 \(m\) 个,那么需要最大化末位 \(lim\)。后缀再选的 \(k-m\) 个划分点的 \(\max\) 必须 \(<lim\)。两部分独立,分别处理前缀选长度 \(i\) 递降子序列的最大末尾值,以及后缀第 \(i\) 小。枚举 \(m\),每次 check 都容易做到 \(\mathcal O(n\log n)\)

总时间复杂度 \(\mathcal O(n\log^2n)\)

782. CSP-S2024 T4(满二叉树,转置)

不是我考场上为啥只有 \(28\) 分啊?????

首先固定树的大小 \(k\),对于不同 \(k\) 分开做,不妨设 \(a_i\leq k\),否则可以对 \(k\)\(\min\)

考虑一个状态下,某个人 \(u\) 获胜的情况。就要求 \(a_u\) 不小于到根路径上,最浅的重边对应深度,且轻边时它的兄弟子树必须晋级失败。预处理到根路径上最浅重边深度 \(down_u\),可以 \(\mathcal O(2^k)\) 从上往下推。\(u\) 向上跳轻边,对应重边子树为 \(u\oplus 1\),这要求到 \(u\oplus 1\) 的点的深度必须尽量小,设为 \(dp_v\),则 \(dp_v>lvl_{fa_v}\) 时,则 \(v\) 子树一定上传成功,会对 \(v\oplus 1\) 子树内都无法成为胜者。关于 \(dp_u\),发现需要记录到根胜者的可能能力值集合 \(S_u\)。使用位运算技巧容易 \(\mathcal O(1)\) 合并与求出 \(dp_u\)。最终对标记下传,可以处理出一个状态下什么点可以成为胜者。

这个做法可以拓展到动态确定一个叶子的值,这样只会修改上的 \(dp_x,S_x\),以及新覆盖 \(\leq k\) 个子树,使得这些子树中的点都无法成为胜者。注意到这是可以暴力执行的:记录 \(f_u\) 表示 \(u\) 子树所有叶子是否都删干净了,那么每次删一个子树,选 \(f_v=0\) 的进行拓展,操作后修改为 \(1\),bfs 执行这个过程。每个点只被删除一次,总时间复杂度 \(\mathcal O(Tn\log n)\),可以获得 \(84\) 分。

注意到:每个人存活时间是一段前缀。且 \(S_x\) 要么为单点,要么是 \(\ge R\) 的任意数值。所以,每次只更新有影响的,发现每个点只更新一次,总点数线性,前述做法暴力修改的复杂度是 \(\mathcal O(Tn)\),卡常后可以在 qoj 和 loj 通过。

【Solution 2】从每个点存活时间均为一段前缀的角度入手,只需要考虑它的祖先中被 ban 掉的最小时间。也就是说,对于每个 \(u\) 处理最小时间,使得 \(dp_u>R\),最终做一遍下传即可。这个是从上往下做的,复杂度也是 \(\mathcal O(Tn)\)

783. P14311(支配对,复杂度分析)

移项可得 \(2a_y\leq a_x+a_z\),因此 \(x,z\) 一定是 \([l,y-1]\)\(\max\) 以及 \([y+1,r]\)\(\max\)。讨论全局最大值 \(mx\) 的情况,如果有 \(\ge 3\) 个,那么取这三个作为 \(x,y,z\) 一定最优。若有 \(2\) 个,一定是作为 \(x,y\),在中间求一下最大值作为 \(y\)。否则问题形如:在 \([l,r]\) 中取 \(x<y\) 使得 \(2a_y\leq x+v\),这是对于左侧的,另一侧同理,问题类似。注意到 \(x\) 一定取前缀最大值,并且 \(a_x<a_y\)\(y\)\(x\) 下一个的前缀最大值。直接分块,块内信息预处理,块间暴力查询。重构和查询都要带 \(\log\),总时间复杂度 \(\mathcal O(n\sqrt n\log n)\)

注意我们依然可以取最值分析。对于上述问题,取 \([l,r]\) 最大值位置在 \(p\)\([l,p-1]\) 最大值位置在 \(q\)。取一下 \([p+1,r]\) 的最大值可以直接更新答案。考虑 \(x=q,y=p\) 时,如果合法就不需要递归 \(F(l,q-1,v)\),否则:\(q<v-2p\),归纳一下递归 \(k\) 层系数大概是 \(2^k\),因此暴力只会递归 \(\log V\) 层。使用线段树维护区间信息查询与修改,时间复杂度 \(\mathcal O(q\log V\log n)\)

784. *qoj14577(贪心,线段树)

起床太晚了没写完 \(\mathcal O(n^2\log n)\)

注意到 \(k_i\in\{l_i,r_i\}\),不然中间截断是不优的,直接枚举 \(k_i\) 并要求方案合法可以得到 \(\mathcal O(2^nn)\) 做法。令最终状态是在 \(R\) 统计答案,\(L\) 是最后一次清空位置 \(+1\)。提取区间 \([L,R]\) 进行分析,对每个怪兽的区间与 \([L,R]\) 的关系讨论:

  • A. 与 \([L,R]\) 只交于 \(L\)
  • B. 与 \([L,R]\) 只交于 \(R\)
  • C. 被 \([L,R]\) 完全包含。

其中 A,C 类区间可能对 \(w(l,r)\) 产生贡献,B,C 类区间必须被选取。确定 \([L,R]\) 时就需要决策 A 类区间的加入情况,处理 B,C 类区间对每个 \((i,i+1)\) 的覆盖次数,那么一定是 A 类区间:根据 \(w\) 从大往小能插入就插入。只考虑 B,C 类区间的影响时,固定 \(L\),显然合法的 \(R\) 是一段前缀,结论是只需要考虑最大的 \(R\),这是因为针对覆盖次数的限制是全局的。对 \(\mathcal O(n)\)\((L,R)\) 都做一遍,复杂度 \(\mathcal O(n^2\log n)\)

注意到 \(L,R\) 本身是双单调的,尝试在双指针过程中直接维护。令选取的 A 类区间集合为 \(S\),每次你可能会删除 \(S\) 中的元素 \(i\),不妨设权值互不相同,此时要会找一个最大的 \(w_j<w_i\) 使得加入 \(j\) 是合法的,此时就是新的最优解。使用线段树维护序列上 \((i,i+1)\) 的覆盖次数,实现指针 \(L\to L+1\) 以及 \(R\to R+1\) 的功能,时间复杂度 \(\mathcal O(n\log n)\)

785. IOI2020 选做

D2T1. qoj1137(数位 dp,反转顺序)

判定一个 \(y\) 是否合法,容易得到从低位往高位贪心的做法,此时要记录低位进位数量。当 \(x=1\) 时,判定为 \(\forall t\leq k\),满足 \(\sum_{i\leq t}2^iy_i\leq \sum_{i\leq t}2^ia_i\),这里是有一些放缩的,因为进位不到这里的可以直接舍去所以是对的。拓展一下就是 \(\sum_{i\leq t}2^iy_i\leq \lfloor\frac{\sum_{i\leq t}2^ia_i}{x}\rfloor\)。右侧是定值 \(lim_i\),可以预处理。

从高往低进行 dp,否则状态数非常大。令 \(f_{i,j}\) 表示将要考虑最低 \(i\) 位,此时 \(y\) 的前 \(i\)\(\leq j\) 的方案数。当 \(j\ge lim_i\) 时是平凡情况 \(F_i=f_{i,lim_i}\)。否则讨论 \(y\) 在这一位的取值,可以从 \(f_{i-1,j}\) 以及 \(f_{i-1,j-2^i}\) 转移。发现每次向下一层除了 \(F\),最多拓展一个状态。总复杂度 \(\mathcal O(qk^2)\)

D1T3. qoj1136(贪心,调整法)

\(m=\frac{n}{2}\),发现可以钦定 \(m\) 个数贡献 \(-1\)\(m\) 个数贡献 \(1\) 的系数,由于题目中是前 \(m\) 大给 \(1\) 后面给 \(-1\),所以这种方式只能算小不会算大。\(k=1\) 时你做法是取 \(-\max-\min\) 最小的 \(m\) 个进行修改,拓展一下就是每行都选的是最大 \(k\) 个,每次选取调整量最小的一对进行调整,没取的一定是一段区间,只能是整体后移。这样调整 \(mk\) 轮即可求出第一问。这样可以求出每行有多少个是 \(+1\),有多少个 \(-1\)。构造方案只需要每次取 \(+1\) 最多的 \(m\) 行以及 \(-1\) 最多的 \(m\) 行。时间复杂度 \(\mathcal O(nm\log nm)\)。这样一定合法,否则可以调整出更优的总答案。

D1T1. *qoj1134(图论建模,重构树)

\(k\to k-1\)。考虑构造任意一个合法排列 \(P\)。先确定 global max 的位置:取 \(r=0\) 且前面 \(k\) 个位置都不是 \(0\) 的位置 \(p\),此时对前面 \(p\)\(r_i\) 都变成 \(r_i-1\)。我们声称一个位置 \(q\) 可以成为当前 max 当且仅当 \(r_q=0\) 且前面 \(k\) 个位置要么被确定要么 \(r'_i>0\)。如此构造的排列一定满足所有相邻 \(k+1\) 个数的大小关系。使用线段树维护,当前 \(r=0\) 的点集以及 ban 点标记,每次未被确定的 \(r=0\) 会导致后面 \(k\) 个位置被 ban 掉。可以以 \(\mathcal O(n\log n)\) 的复杂度求出排列 \(P\)

注意到 \(k=1\) 时,能确定的只有相邻两点的大小关系,猜测:\(k\) 更大时确定的是所有相邻 \(k+1\) 个点两两的大小关系。在图 \(G\) 上,若 \(\text{dist}(u,v)\leq k\),根据 \(P_u,P_v\) 的关系连边 \(u,v\) 并定向。最终查询 \(u\) 是否可达 \(v\) 或者反过来。

看上去就很能优化,首先倍长一下使得环变为序列。扫描线一下值域去掉 \(a_u>a_v\) 的限制,由于只需要描述可达性所以可以少很多边。具体来说只需要找 \([u-k,u-1]\) 中最大的 \(a_v<a_u\) 以及 \([u+1,u+k]\) 中最大的 \(a_v<a_u\),这样连出两条边 \(u\to v_1\to v_2\)。分别称为 \(l_u,r_u\),对于 \(u\) 不断向左倍增到首个覆盖 \(v\) 的位置,然后向右倍增即可。时间复杂度 \(\mathcal O((n+q)\log n)\)

786. 20251027 模拟赛

A. qoj8523(构造)

考虑构造简单操作,比如交换 \(a_x,b_y\),令 \(a\) 中为 \(xA\)\(b\) 中为 \(By\),其中 \(|A|=k,|B|=k-1\),第一次操作为 \(xBy,A\),第二次操作为 \(Ay,xB\)。注意只关心数集,所以用 \(2\) 次操作交换两个串中的元素是可以接受的,执行 \(\frac{n}{2}\) 次即可调对。

直接使用平衡树就是 \(n\log n\)。但是直接使用 deque 维护格子的 \(xA,By\),大小分别为 \(k+1,k\),即这个滑动窗口。时间复杂度 \(\mathcal O(n)\)

B(mex,偏序降维)

首先求出 \(\mathcal O(n)\) 个极小 \(\text{mex}\) 区间 \((l_i,r_i,v)\)。实现主席树求区间 \(\text{mex}\) 后,在 \(I_{v-1}\) 的区间 \([l_1,r_1]\) 找两侧第一个 \(v\) 得到 \([l,r]\),加入\([l,r_1],[l_1,r]\) 到对应的 \(I_{\text{mex}}\) 上。求 \(I_v\) 时将包含别的区间的区间去除,对 \(r\) 排序后维护 \(mxl\) 即可。另一个做法是直接扫描线序列,后缀 \(\text{mex}\) 极长段只会变化 \(\mathcal O(n)\) 次,用类似于颜色段均摊的手法找到这些事件。

问题变为:查询 \([L,R]\) 包含的 \([l_i,r_i]\) 长度 \(\leq k\) 中最大的 \(v_i\)。直接放在二维平面上刻画,拆成三个区域即可(\(\max\) 允许重复)。对于蓝色和绿色三角形,变为普通的包含,没有 \(k\) 的限制,扫描线序列即可;对于黄色区域,对于平面旋转 \(45\) 度(变换到 \((r-l,l+r)\))后变为 3-side 矩形,按照 \(r-l\) 扫描线即可。均可线段树维护单点修改区间 \(\max\),时间复杂度 \(\mathcal O(n\log n)\)

C. *loj536(博弈,二分图,结论)

考虑图论模型:对每张牌建一个点,向能够作为它后继的点连边,这是一个二分图。转化为:初始时在二分图的一个点上,两人轮流沿着边走,不允许重复访问节点,不能移动者输。结论:起点是先手必胜的,当且仅当它在所有最大匹配上

优化一下连边跑网络流,注意到一个点 \(u\) 一定在最大匹配中等价于所有最大流中 \(S\) 到该点 \(u\) 的边有流量。等价于:在某个最大流中 \(S\)\(u\) 的边有流量,且残量网络上不存在 \(S\)\(u\) 的路径。时间复杂度 \(\mathcal O(n^{5/3})\)

787. ucup 3-10

https://qoj.ac/contest/1803

F. qoj9406(字符串)

不妨设 \(S_a\leq S_b\leq S_c\),那么只有 \(S_a+S_b>S_c\) 或者 \(S_b+S_a>S_c\) 的限制。令 \(x=S_a,y=S_b,s=S_c\),不妨设 \(xy>yx\),等价于 \(x^{\infty}>y^{\infty}\),因此是偏序关系,可以预处理出排名。注意到 \(x+y>s\wedge x\leq s\) 的必要条件是 \(x\)\(s\) 的前缀。因此可以直接枚举 \(x,s\),限制只剩下 \(y>\text{suffix}(s)\)。对于所有后缀接在一起做后缀排序,总的限制就是二维偏序。然后处理一下重复的问题就可以了,时间复杂度 \(\mathcal O(n\log n)\)

L. qoj9411(字典树)

\([0,2^{60}-1]\) 的线段树上拆分 \([l,r]\),转化为 \(q\log V\) 次求一个后缀任意取的答案。

\(a_i\) 插入字典树,全体 \(\text{xor}\)\(x\) 就是等价于,如果 \(x\) 的二进制第 \(d\) 位为 \(1\),就需要将该深度的所有节点交换左右子树。先走前缀固定部分的贡献,高位的贡献也容易确定,最终会走到一个子树 \(u\) 上,现在问题形如:令 \(u\) 深度为 \(d\),给定 \(k\) 求所有 \(x\in[0,2^d-1]\)\(f(x,k)\) 之和。发现这个可以在 trie 树上直接 dp,\(k\) 只存到 \([0,\text{size}_u]\),总和是 \(n\log V\) 因此正确。时空复杂度 \(\mathcal O(n\log V)\)

J. qoj9421(图论)

注意到 \(u,v\) 间存在二元环时,\(u,v\) 最终连边集合一样,可以缩成一个等价类,最终一个等价类内部是两两有双向边的。等价类之间的边是完全二分图。最终每个等价类显然最多有一条出边。注意到前述情况事实上还会进一步合并,也就是说一个 \(>1\) 的等价类连出去的东西还会被合并进来,因此一个连通块最多只能出现一个等价类在树根的位置。

最终图 \(G'\) 每个连通块的形态只能是以下三种:内向树/内向基环树/树根为团,子树连了若干边。预处理一些系数以及判祖先关系的东西之后,容易做到 \(\mathcal O(n\log n)\) 的复杂度。

788. atcoder-yahoo-procon2018-qual-d(异或,钦定主元)

下面的加法都是异或。首先对 \(A\) 矩阵全体 \(+x\),然后令 \(y\to y+x\),限制为 \(a_i+a_j+A_{i,j}\in\{0,y\}\)。先考虑 \(y=0\) 的情况:注意到此时 \(a_i\) 都可以用 \(a_1+v_i\) 表示,再检查一下 \(v\) 之间是否满足 \(A\)。最终枚举 \(a_1\) 的值,计算这个组合是否合法即可。拓展到 \(y\ne 0\),此时 \(a_i\in\{a_1+A_{1,i},a_1+A_{1,i}+y\}\)。考虑 \(A_{i,j}\) 的限制,就只要求 \(A_{1,i}+A_{1,j}+A_{i,j}\in\{0,y\}\)

此时枚举 \(a_1\),每个点就有两种取值 \(a_i,b_i\),满足 \(b_i=a_i+y\)。将 \(p+q=y\)\((p,q)\) 取出,考虑取 \((a_i,b_i)=(p,q)\) 的有 \(t\) 个,在序列中 \(p\) 出现 \(c\) 次,\(q\) 出现 \(d\) 次,这里组合数前缀一下就好了。视值域与 \(n\) 同阶,时间复杂度 \(\mathcal O(n^2)\)

789. 20251028 模拟赛

*B(位运算,线段树)

先求 \(f(a,b)\),打表发现最优的 \(x\) 满足 \(x\subseteq b\),否则考虑 \(x\)\(1\)\(b\)\(0\) 的一位,去掉这个是无影响的。烦人的异或就可以转为减法,在满足 \(x\subseteq b\) 的条件下,就转化为 \(a+x\ge b-x\),即 \(x\leq\frac{b-a}{2}\)

\(n\) 为偶数时可以得到 \(g(n)=4g(\frac{n}{2})\);当 \(n\) 为奇数时,考虑与 \(g(n-1)=4g(\frac{n-1}{2})\) 的差异,考虑 \(f(a,n)\)。若 \(\frac{n-a-1}{2}\subseteq n-1\),那么 \(f(a,n-1)=\frac{n-a-1}{2}\),但是 \(f(a,n)\) 取不到,此时 \(f(a,n)=f(a,n-1)+1\)。若 \(\frac{n-a}{2}\subseteq n\)\(\frac{n-a}{2}\) 为奇数,则 \(f(a,n)<f(a,n-1)\),此时 \(a\) 要找到 \(b\subseteq n-1\)\(\frac{n-a}{2}\) 的后继。对于 case 1,增量贡献为 \(2^{\text{popcount}(n)-2}\),对于 case 2,总贡献是 \(2^{\text{highbit}(n)}-2^{\text{popcount}(n)-2}\)

结论是,当 \(n\) 为奇数时,\(g(n)=4g(\frac{n-1}{2})+2^{\text{popcount}(n)-1}-2^{\text{highbit}}(n)\)。将贡献拆开,容易使用线段树维护,时间复杂度 \(\mathcal O(n\log n)\)

C(极小 mex 区间)

首先求出 \(\mathcal O(n)\) 个极小 \(\text{mex}\) 区间,每个值单独拉出来,区间是双单调的,可以得出 \(\mathcal O(n)\) 个 3-side 贡献矩形,即 \(l\in[l_1,l_2],r\ge r'\)。对 \(l_1,l_2\) 差分转化为 2-side 矩形。对询问差分成两个 2-side 矩形的差,即 \(Q(l,r)\) 计算 \(l'\leq l,r\leq r'\) 的权值和。

贡献形如 \(\min(l',l)(r'-r+1)\),将这些矩形放在 \(r\) 上,对此分块,处理前面整块以及散块内部的贡献(类似于分块平衡),时间复杂度 \(\mathcal O(n\sqrt n+q)\),也可以主席树维护历史和做到 \(\mathcal O((n+q)\log n)\)

D(分类讨论,线段树分治)

固定 \(j\)\(a_i\) 取前缀最大值,若 \(a_i>a_j\)\(k\) 取后缀最大值否则是后缀最小值。容易有 \(\mathcal O(nq)\) 做法。

定期重构,将点分为固定点和动点。动点为 \(j\) 或者动点为 \(i,k\) 是容易的。完全是动点或者完全是固定点可以套用上述做法做。现在要考虑:动点为 \(i\),固定点为 \(j,k\) 或者动点为 \(k\),固定点为 \(i,j\)。修改动点时,每个动点在这两种情况的贡献是独立的,可以分别用可删堆维护。

  • \(i=x\),那么 \((i,j,k)\) 被统计到的必要条件是 \(a_i\)\(a_{1\sim j-1}\) 内的最大值。那么找到 \(x\) 后面第一个 \(\ge a_x\) 的位置,设为 \(y\)。特判 \(j\ge y\) 或者 \(y\) 不存在(取后缀次大最大值),此时 \(j<y\),有 \(a_j<a_i\)。那么 \(k\) 取后缀 \(\max\),移项发现 \(j\) 取最小值最优。
  • \(k=x\),讨论 \(a_k\) 作为 \(\min,\max\) 的情况。若 \(k\)\(\max\),那么找到 \(x\) 前面第一个 \(\ge a_x\) 的位置,设为 \(y\)。如果 \(y\) 存在,只需要考虑 \(y=j,y<j\),前者直接算,后者取 \(\min j\)。如果 \(y\) 不存在,则 \(a_k\) 是 globalmax。此时位置关系可以忽略。此时 \(a_j\)\(a_{i+1∼n}\) 内的最小值,\(a_i\)\(a_{1\sim j-1}\) 内的最大值,预处理这些对,只有 \(\mathcal O(n)\) 个,李超树维护贡献即可。若 \(k\)\(\min\),也只有少量情况。

时间复杂度 \(\mathcal O(n\sqrt n\log n)\)。注意到定期重构事实上是两层的线段树分治,上述做法可以直接支持插入,因此可以直接转化为线段树分治,支持动态插入点算贡献,并加入“固定点”集合。李超树以及线段树维护,时间复杂度 \(\mathcal O(n\log^2n)\)

790. ucup 3-11

https://qoj.ac/contest/1804

F. *qoj9440(解集调整,凸函数,平衡树)

有显然的 \(\mathcal O(n^3)\) 区间 dp 做法。先优化到 \(n^2\),仍然是区间 dp,发现每次修建 \(l\) 或者修建 \(r\) 一定比修建中间的点更优。枚举最终被修建的车站 \(p\),此时要将 \([1,p]\)\([p+1,n]\) 的操作序列归并。设序列 \(b_i=a_i-a_{i-1}\),左边的 \(b\) 序列记作 \(x_i\),右边的序列的翻转记作 \(y_i\)。相当于要把 \(x,y\) 归并起来,产生的代价为:对于每个 \(x_i\),产生的代价是在归并后序列里排在他前面的 \(y\) 的个数乘上 \(x_i\),对于 \(y_i\) 同理,最终加上 \(n(a_{p+1}-a_{p-1})\)

给定 \(x,y\) 后,发现如果 \(x_i>x_{i+1}\) 那么 \(i,i+1\) 一定是连续的,可以替换为 \(2\)\(\frac{x_i+x_{i+1}}{2}\),进一步地可以把 \(x\) 缩成若干连续段,满足每个段形如 \((sum,cnt)\),满足 \(\frac{sum}{cnt}\) 递增。对于这样的 \(x',y'\) 序列按照 \(\frac{sum}{cnt}\) 递增的顺序进行归并。本质上其实是 exchange argument。直接扫描线 \(p\),预处理 \(y\) 的结果,每次会进行撤销,直接维护所有 \(x\) 的段,使用栈来维护。离散化后全局维护一个值域线段树描述归并的结果,时间复杂度 \(\mathcal O(n\log n)\)

O. qoj9449(可行性转方案数背包)

每次贪心扫,能加就加。如果在同一个连通块那么是平凡的,可以拓展域并查集维护。否则需要合并两个连通块,这样有效的边数至多是 \(n-1\)。最终限制黑白均为 \(n\) 个点,每个是在 \(x,y\) 中二选一要加出来 \(n\)。改成选 \(\min(x,y)\) 后可以选择是否加入 \(\max(x,y)-\min(x,y)\)

本质不同的 \(\max-\min\) 很少,只有 \(\sqrt n\) 种。对于每种预处理一个 bitset,最终进行合并,因为要做 \(n\) 次所以复杂度 \(\mathcal O(\frac{n^2\sqrt n}{\omega})\)。不如直接任取模数,这样背包可以删除物品,复杂度变为 \(\mathcal O(n^2+m)\)

791. 20251030 联考 D(组合意义)

瓶颈在于给定 \(a_i,k\)\([x^k]\prod_{i=1}^n\sum_{t\ge 0}\frac{x^ta_i^t}{t!}\)

这个东西很像多重集组合数,确定一组贡献方案 \(t_i\),满足 \(\sum t_i=k\)。发现一组对 \([1,k]\) 每个位置染色与 \(\{t_i\}\) 形成双射。此时每个位置产生对应颜色的贡献。注意最终要除以 \(k!\)(多重集组合数的分子)。所有方案的贡献和显然是 \((\sum a_i)^k\),于是答案就是 \(\frac{(\sum a_i)^k}{k!}\)

792. 20251030 zr

C(复杂度平衡,网格图)

直接记录最后 \(k\) 位的状态以及 \(x'\),显然有 \(\mathcal O(n^32^k)\) 做法。考虑以 \(k\) 为块长,不妨设 \(n\)\(k\) 的倍数,拆成 \(\frac{n}{k}\) 块。块内部可以相互贡献。在最外层枚举所有块内部 \(1\) 的个数,此时 \(x'\) 需要关心块之间的贡献。考虑一起处理所有块,在所有块中位置从 \(1\) 扫到 \(k\),记录当前每块已填 \(1\) 的个数,显然每次填一个数,前面一个块的贡献也是能算的。在 \(n=50\) 时,直接分三块计算即可。

时间复杂度 \(\mathcal O(n^3\min(k^{\frac{n}{k}},2^k))\)。类似题目:[CTT2024] 乘积的期望

D(拆贡献,置换环,平衡树)

显然先执行操作 \(2\) 再执行操作 \(1\),操作后答案是 \(n-\#cycle\)。令这个前缀是 \([1,x]\)。对于一个重排 \([1,x]\) 的方案,将 \(\leq x\) 的数设置为黑点。先不管全白的环,发现一个黑色连续段可以直接断成若干自环;一个黑白交替的最终也可以拆为若干二元环(黑点只有一个,白点可以有很多)。进一步拆贡献,发现只关心:存在黑点的环数,所有 \(black\to black\) 边的数量,所有 \(black\to white\) 边的数量。

尝试直接维护所有 \(cost_x\)。后两者直接拆到每条边上,前者需要用平衡树维护环内最小值。时间复杂度 \(\mathcal O(q\log n)\)

793. Pinely Round #5

https://codeforces.com/contest/2161

D. CF2161D(转置,dp)

转置一下维度就可以 dp 了。

E. CF2161E(计数)

研究对象是合法数列,考虑一下合法数列的性质。

显然一个连续段可以只关心最后一个位置的合法性。找到 \([1,n-k+1]\) 中首个 \(01\) 或者 \(10\),发现后面 \(k-1\) 个位置数量平衡,后续形成的是循环节。预处理组合数之类的就可以做。时间复杂度 \(\mathcal O(n)\)

F. CF2161F(代表元思想)

对于 \(f(S)\),可以枚举阈值 \(0\leq r<n\),将所有 \(\text{dist}(u,v)\leq r\) 的连边,对答案计入连通块个数 \(-1\) 的贡献。对于连通块考虑钦定一个代表元,处理树的 bfs 序 \(bfn\),那么取 \(bfn\) 最小的作为代表元。转化为每个点在多少 \(S\) 中成为代表元。限制即为,不存在 \(bfn\) 更小的点抢掉它的代表元地位。预处理 \(f_{u,i}\) 表示有多少 \(bfn_v<bfn_u,\text{dist}(u,v)=i\),做一个前缀和即可。时间复杂度 \(\mathcal O(n^2)\)

G. CF2161G(位运算)

先把所有数调到最小的 \(b_i\ge a_i\) 使得 \(X\subseteq b_i\),发现最优情况下,最多有一个 \(a'_i>b_i\)。考虑 \(S=(\cap b_i)-X\),最终需要 \(S=0\)。令 \(k=\max S\),最终要选取一个位置 \(p>k\),保证某个数第 \(p\) 位为 \(0\) 且剩余位置不全为 \(1\),将 \(S\) 清空调到 \(p\)。如果有多个可选的,选取低位最大的求和。首先求 \(\sum b-\sum a\),再考虑暴力找到最小的 \(p\)。从高往低找 \(X\) 的最高位使得不在 \(\cap a_i\) 中然后修改低位,再接着做。发现需要一个 or 卷积状物,注意到值域是比较小的,所以可以预处理信息。后面比较 trivial。

794. qoj9624(计数,区间 dp)

\(x\) 删除了 \(y\) 则连边 \(x\to y\),显然最终图只有若干链。尝试研究最终被保留下的人,发现它作为链头时,必然是链对应的连续区间的端点,左右由自身字符决定。链一定是一个区间 \([l,r]\),并且由 \([l,r-1],[l,r+1]\) 拓展而来。存活但不染黑别人事实上只有 \((1,L)\) 以及 \((n,R)\)。对于每条链,只需要要求链尾不放在第一个即可,特例是 \((1,L),(n,R)\),发现此时形态非常特殊,必然是 \(LLLL\) 或者 \(RRR\),加上这种贡献即可。

很好的性质是链之间独立,因此统计答案直接做 2D-1D 的 dp,为 \(f_{i,j}\) 表示 \(i\) 是第 \(j\) 条链的右端点的方案数,每次并上一个区间乘上方案数 \(w_{l,r}\) 即可。形成链的方案数容易区间 dp。时间复杂度 \(\mathcal O(n^3)\)

795. qoj4271(树上 dp,子问题设计)

注意到停留在某个点当且仅当这个子树都被填满了。当 \(u\) 并未收到上面的球时,最终的空位数是确定的。从下往上合并子树,考虑怎么设计子问题,发现是 \(fa_u\to u\) 下传了 \(k\) 个球,那么只要处理内部的方案数即可。由于这 \(k\) 个球都是不自由的,所以不同的顺序一定会对应不同的结果。

进一步考虑这 \(a_u\) 个可以自由决策的球,就可以先去填满某个子树,插入在这 \(k\) 个球的序列中间。

\(k\) 个球初始都带有默认方向。你发现这样钦定好了落到哪个子树里面也会进一步对应不同的结果。视 \(n,k\) 同阶,时间复杂度 \(\mathcal O(n^2)\)

796. 20251102 梦熊模拟

?是不是太板子了。

C. P14380(虚树,历史和)

\(P(u,v)\) 表示 \(u\to v\) 路径上的点集,那么有 \(f(l,r)=P(l,l+1)\cup P(l+1,l+2)\cup\cdots\cup P(r-1,r)\)。注意到 \(f(l+1,r)\subseteq f(l,r),f(l,r-1)\subseteq f(l,r)\),因此一个 \(f(l,r)\) 有效当且仅当前面两个都是它的真子集。而 \(f(l+1,r)\subseteq f(l,r)\) 等价于 \(P(l,l+1)\subseteq f(l+1,r)\)。直接扫描线 \(l\),对树链做值覆盖,求一下 \(P(l,l+1)\) 上的最大值,就是使得这个条件成立的最小 \(r\)。对于 \(r\) 同理可以找到这样的 \(l\)。这里有 \(n\) 次树链赋值,\(n\) 次查树链 \(\min,\max\)。可以使用全局平衡二叉树降低复杂度。

有这两个信息之后,就会在平面上 ban 掉一些 \(1\times t\) 或者 \(t\times 1\) 的矩形,现在要查询 \([l,r]\times[l,r]\) 内部没被覆盖的点数。直接扫描线 \(r\),维护历史和线段树即可。时间复杂度 \(\mathcal O(n\log n)\)

D. P14381(拆贡献,分治)

将值按照是否 \(\leq \sqrt w\) 分开,称为小数和大数。显然小数之间可以任意放,但大数不能相邻,并且会根据限制插入到某些小数的空中。将小数从大到小加入,这时大数能加的位置越来越多,限制越来越松。记录合法的空数即可,发现是可以转移的。还有一个问题是怎么处理 \(f(A)\),注意到 \((a_i-a_{i-1}+1)^t\) 的意义是 \([a_{i-1},a_i]\) 中有序的选出来 \(t\) 个数,这样扫值域的时候记录一下当前考虑的 \(a_l,a_r\) 这一部分已经选出来了 \(p,q\) 个数,转移是容易的。时间复杂度 \(\mathcal O(kn^3t^3)\),看上去就很能优化,不管了。

797. P10201(结论猜测,线段树分治)

不妨设整张图连通,猜测非平凡情况下是一定有解的。一种显然的平凡情况是所有格子权值相等,进一步做黑白染色,发现如果同色格子全部相同那么也是平凡的。暴力预处理,复杂度 \(B^2mod\)。我们声称剩余情况一定是所有 \(v\) 都有解的。这样你直接做线段树分治,并查集支持一下撤销,就可以规避掉删除。总时间复杂度 \(\mathcal O((nm+q)\log q\log nm)\)

抄个证明。找到三个四连通位置,依次为 \(a,b,c\),保证 \(a\neq c\)。结论是这三个位置可以走出全部 \(v\),将路径形态设计为 \(b?b?b\cdots?b\) 即可。这里 \(?\) 可以取 \(a,c\),而 \(mod\) 是质数,每个 \(?\) 的贡献是 \(10^{2k}\)。由于 \(a\neq c\) 所以很可以调整。

798. P11712(图论,二分图,dfs 生成树,异或哈希)

取一棵 dfs 生成树分析。考虑删一条边的情况,对树进行黑白染色后,如果连接同色点的非树边恰好有一条,那么可以删掉这条非树边。考虑删树边的情况,此时它需要在所有同色非树边的交集上,并且不被任意异色非树边覆盖。可以简单树上差分实现。

拓展到两条边的情况。若为两条非树边那么平凡,只需要考虑同色非树边数量是否恰好为 \(2\)。否则枚举其中一条树边 \(e\),如果其被异色非树边覆盖,显然需要这个数量恰好为 \(1\),并且所有同色非树边都覆盖 \(e\)。对剩下的情况,断开的树边一定不被异色非树边覆盖。设为 \(e_1,e_2\),此时断开 \(e_1,e_2\),只考虑同色非树边的限制,就要求每条边连接不同部分,并且三种组合不全有边。当 \(e_1,e_2\) 不成祖先关系或者所有边都不同时覆盖 \(e_1,e_2\) 时,令 \(S(e)\) 表示覆盖 \(e\) 的非树边集合,此时就是 \(S(e_1)\cap S(e_2)=\varnothing,S(e_1)\cup S(e_2)=U\),使用 xor-hashing 即可刻画;如果所有边同时覆盖 \(e_1\),你发现第一问答案为 \(1\),自然就不用考虑了。这样对于所有同色非树边赋予随机权值,做异或树上差分即可。

使用哈希表维护,时间复杂度 \(\mathcal O(n+m)\)

799. qoj13168(kruskal 重构树,支配点对)

考虑对于所有边按照 \(w\) 排序,每次合并两端不连通的边即可得到 \(\mathcal O(nq)\) 做法。显然,只有原图 MST 上的边是有效的。使用 kruskal 重构树 \(T\) 来刻画,如果一个点对应的边的两个儿子都有黑点,那么这条边就不会被选取。发现这类点的数量其实是固定的,即为 \(|S|-1\)。由于所有点都在叶子上,进而可知这些点就是按照 \(\text{dfn}\) 排序后相邻所有点的 \(\text{lca}\)。对 \([l,r]\) 进行类似于 PKUWC2025 D1T2 的回滚莫队,即使用仅删除的手法来保证前驱后继都可以 \(\mathcal O(1)\) 回答,时间复杂度 \(\mathcal O(n\sqrt q)\)

回滚莫队并不必要,考虑支配点对。每个点只有两个儿子,只需要左子树取一个右子树取一个即可。直接枚举大小较小一方的所有点,在另一侧找到前驱后继,总共只有 \(\mathcal O(n\log n)\) 个贡献矩形。最终扫描线加树状数组回答询问,时间复杂度 \(\mathcal O(n\log^2n+q\log n)\)

800. *loj6878(折半,异或,容斥)

首先将回文写成 \(\oplus (a_i\oplus a_i^R)=0\),这样只需要关心低 \(\frac{m}{2}\) 位的值,将原先的第 \(i\) 位以及第 \(m-1-i\) 位叠在一起即可。将 \([l,r]\) 放在 \([0,2^m-1]\) 的线段树上做拆分,可以拆成 \(\leq m\)\([p2^k,(p+1)2^k-1]\)。可以说明经过这样的映射,整区间还是整区间,即为 \([0,2^{m/2})\) 内某整区间 \([l',r']\) 重复出现若干遍的结果。对于每个 \([l_i,r_i]\),其可以视作是不超过 \(2m\) 个整区间的线性组合,现需求出这些线性组合进行异或卷积后 \(0\) 处的结果即可。

注意到,当 \(l_i=0\) 时,\([0,x-1]\) 所拆出的区间形如线段树上一条链向外连出的若干点。对于这样的两个链式结构做异或卷积,得到的结构仍然相同。因此可以在多项式复杂度解决 \(l=0\)。进一步进行容斥,将 \([l_i,r_i]\) 差分为 \([0,r_{i}+1)−[0,l_i)\),结合对 \(n\) 个位置 meet in middle 的折半。时间复杂度 \(\mathcal O(2^{\frac{n}{2}}m^2)\),精细实现可以只带一个 \(m\)

801. CF2034H(数论,搜索)

\(m=10^5\) 表示值域。一个子集合法当且仅当 \(\forall i\in S\)\(i\neq j,j\in S\) 满足 \(\gcd(j)\) 不为 \(i\) 的因数。换而言之,每个元素上都存在某个指数,使得它在这意维是严格最小的。

反过来枚举这个最小值具体的形态,令子集为 \(a_1,a_2,\cdots,a_k\)。对于每个 \(1\leq i\leq k\) 选取一个 \((p_i,d_i)\),使得所有 \(i\ne j\)\(a_j\) 都是 \(p_i^{d_i}\) 的倍数,且 \(a_i\)\(p_i\) 上的指数 \(<d_i\)。注意到当 \(k>2\) 时,所有数去掉最小值的乘积一定 \(\leq m\)。尝试直接爆搜所有 \((p_i,d_i)\) 的组合。预处理每个 \(x\) 有多少是它的倍数,容易判定一个组合是否合法。这样的组合数并不多,对 \(p_i^{d_i}\) 排序后,首个 \(\leq \sqrt m\),后面总乘积 \(\leq m\),因此一个上界是 \(\frac{m\sqrt m}{\log m}\)。对于 \(k=1\) 平凡,\(k=2\) 直接排序后看是否有相邻不成倍数的,时间复杂度 \(\mathcal O(T\frac{m\sqrt m}{\log m}\omega(m))\)

802. qoj3843(树的拓扑序,反转 dp)

绝对值函数难以处理,考虑直接拆贡献,计算所有 \(u,v\) 在拓扑序上为前后相邻位置的方案数。

\(u\)\(v\) 的祖先时,发现只能是 \(u=fa_v\)。这样将 \(u,v\) 缩成一个点后,对 \(n-1\) 个点的树 \(T'\) 求一下总拓扑序数量。直接枚举 \(n-1\)\((u,v)\),每次重新计算即可,这一部分复杂度 \(\mathcal O(n^2)\)

否则此时 \(u,v\) 无祖先关系,令 \(t=\text{lca}(u,v)\),提取出 \(u\to t\) 以及 \(v\to t\) 的两条路径 \(P_u,P_v\) 进行归并。尝试对 \(P_u,P_v\) 的归并过程进行 dp,可以先预处理每个子树去掉一个方向子树的方案树 \(g_{u,v},v\in son_u\)。归并过程的 dp 就是 \(P_u\) 考虑到第 \(i\) 个点,\(P_v\) 考虑到第 \(j\) 个点,此时考虑完 \(P_u(1\sim i),P_v(1\sim j)\) 以及其所有子树的方案数 \(F_{i,j}\),可以由 \(F_{i-1,j},F_{i,j-1}\) 转移。\(t\) 以上的部分仿照第一部分处理即可,总复杂度 \(\mathcal O(n^4)\)

注意到 \(u,v\) 相当于只在 \(F_{u,v}\) 赋了初值。将 \(P_u,P_v\) 上的点修改为两个不交子树意义不变。对于全局的 \(u,v\) 一起计算,那么 \(F\) 数组可以放到一起,因为转移流程完全相同。可以视为 \(\Omega(n^2)\) 个节点的有向图,然后在 \(F_{u,v}\) 赋初值,求到 \(F_{t,t}\) 的贡献和。将 dp 过程反转,在所有 \(F_{t,t}\) 赋初值,然后在所有 \(F_{u,v}\) 算贡献。时间复杂度 \(\mathcal O(n^2)\)

另一个做法是直接拆绝对值函数,转化为 \(\sum [\min(a,b)\leq x<\max(a,b)]\),这样点权只有 \(0,1\),转化为算所有相邻位置异或之和。

803. CF2164F2(树的拓扑序)

按照值从小往大填,显然能填 \(1\) 的一定是当前树上,子树中没有别的 \(0\)\(a_u=0\)\(u\),将其加入备选队列 \(q\)。每次取出 \(u\),对子树内所有未删除的点 \(v\)\(a_v\to a_v-1\)。用一个重构图 \(G\) 来描述限制,如果产生新的 \(a_v=0\),找到这些点中所有子树中没有别的 \(0\) 的位置,在 \(G\) 上向它们连边并加入队列;如果并没有,那么找到祖先中首个 \(0\) 向它连边。如果此时它的子树中没有别的 \(0\) 那么就加入队列。

如此可以构造图 \(G\),此时排列 \(p\) 合法当且仅当 \(p\) 是一个 \(G\) 的拓扑序。\(G\) 是一张极为特殊的 DAG,满足 \(1\) 在拓扑序的位置固定。对 \(G\) 进行:叠合杏仁,缩二度点构成的链这两种操作后,最终 \(G\) 的形态是:取出所有可达 \(1\) 的点,子图是一张以 \(1\) 为根的内向树;取出所有 \(1\) 可达的点,子图是一张以 \(1\) 为根的外向树;使用队列维护简化 \(G\) 的流程,最终贡献就与树的拓扑序求法类似。

在构造 \(G\) 的过程中使用树剖线段树维护区间最小值信息,每次取 \(\text{dfn}\) 最大的,以及在树链上倍增即可降低复杂度。取出来一个之后就把所有祖先 ban 掉,可以维护权值 \(b_i\)。线段树维护的信息为 \(\min(b_i)\) 以及所有 \(\min(b_i)\) 中的 \(\min(a_i)\),这样就可以合并了。线段树二分首先要求 \(\min(b_i)=0\),再要求这里面的 \(\min(a_i)=0\)

时间复杂度 \(\mathcal O(n\log^2n)\),如果使用全局平衡二叉树,时间复杂度 \(\mathcal O(n\log n)\)

804. 2025 Xi'an Regional

我的题:C,G,J,K,M,赛后自己会了 A。

A. qoj14681(线段树)

方便起见,对全体离散化使得 \(a_i,b_i\) 互不相同。

考虑静态问题。假设使用 \(a\) 的 global max 可以击杀掉 \(t\) 个,无法被 global max 击败的是不可能被删除的,但实际答案可能取到 \(t+1\),原因是 global max 可能被击杀掉。转为判定是否可以取到 \(t+1\)。注意到这 \(t+1\) 中的最后一个一定是不可能被删除的中的 \(\max a\) 击败,记为 \(v_2\)。令 \(\max a=v_1\)。如果 \(\max a\) 对应的 \(b_p\leq v_2\) 那么直接结束,否则需要考虑 \(b_p\in(v_2,v_1]\) 的情况,为了消掉它,需要找到 \(a_q\ge b_p\ge b_q\),进而需要消掉 \(q\),依此类推,最终需要令 \(b\) 落在 \(\leq v_2\) 的区域。如果存在这样的一条链,那么答案就是 \(t+1\)

在跳跃过程可以只保留 \(b_i<a_i\) 的线段,直接找这条链是不必要的,改成判这条链是否被割开即可。换而言之,找到一个位置 \(pos\) 使得所有前面线段有 \(a_i<pos\) 或者 \(pos\leq b_i\) 成立。也就是说对 \((b_i,a_i]\) 做区间覆盖,要求 \((v_2,v_1]\) 均被覆盖即可。线段树维护一下区间加区间 \(\min\) 即可。查询 \(v_2\) 形如查询后缀的 \(\max a\)。将其插到叶子上的可删堆变成单点修区间 \(\max\),时间复杂度 \(\mathcal O(n\log n)\)

C. qoj14683(博弈,双指针)

手玩发现判定条件是所有连通块都是链上直接挂一车点(毛毛虫)。双指针然后维护每个点的所有邻居的度数,因为判定是摘掉所有一度点后剩下的是链,显然是支持增删的。对每个 \(l\) 处理出最大的 \(r\) 使得其合法,询问只需要判定是否有 \(r\leq f_l\)。时间复杂度 \(\mathcal O(n+q)\)

K. qoj14691(弱化限制,网络流)

判掉全相等。直接弱化为 \(b_i\subseteq a_i\cap p_i\),核心限制在于 \(b_i\subseteq p_i\),显然可以跑网络流,可以只连超立方体的边进行优化建图,来做到边数 \(n\log n\)。可以说明这样一定存在全部取等的情况,因为这样不断调整即可,每个局面的 \(a\) 如此操作后一定会减小。时间复杂度 \(\mathcal O(n\sqrt{n\log n})\)

M. qoj14693(条件推导)

如果 \(a_1=1\),当且仅当 \(a\) 中所有元素均为 \(1\)\(n\) 为奇数时,\(a\) 不是好的。进一步,发现可以将 \(a_i\in[2,n-1]\) 的任意一个数移动到边界上使其成为 \(1\),并且不会出现前述非法情况。因此非法的数列一定满足 \(a_i\in\{1\}\cup[n,m]\)。考虑统计非法序列的个数,用总数来容斥,直接 dp,暴力消栈记录当前序列是否为空即可,时间复杂度 \(\mathcal O(n)\)

805. *qoj5504(2-SAT,线段树优化建图)

每个位置二选一考虑用 2-SAT 描述。虽然研究对象是对序列用两种颜色的染色,但是观察到两种颜色限制相同,因此地位等价,不妨\(\boldsymbol{1}\) 为核心颜色分析,转化为限制 \(1\) 的出现次数为 \([n,2n]\)。将 \([a_i,b_i]\)\(0\) 或者 \([c_i,d_i]\)\(1\) 转化为,如果 \([a_i,b_i]\) 中任意一个位置为 \(1\),那么 \([c_i,d_i]\) 全部为 \(1\)。即 \(x_p=1\to x_q=1,\forall p\in[a_i,b_i],q\in[c_i,d_i]\)。现在问题转化为快速取出一个大小在 \([n,2n]\) 中的闭合子图。

\(G\) 缩 scc 得到 dag,转化为选 dag 上的闭合子图。令每个 scc 的大小为 \(a_i\),发现如果 \(\max a_i<n\),那么按照拓扑序降序后一定存在某个时刻的前缀和落在 \([n,2n]\) 中,直接贪心求即可;否则此时存在大小 \(\ge n\) 的 scc,取出来它,如果它的大小 \(>2n\) 则全局无解,否则考虑它放在 \(0\) 还是 \(1\)。由于 \(G\) 的反图是以 \(0\) 为核心颜色的图,所以只需要比较:它可达的节点,以及可达它的节点中的较小者,这样和一定是 \(\leq 2n\) 的。

区间向区间连边,线段树优化建边即可。设 \(3n,q\) 同阶,时间复杂度 \(\mathcal O(n\log n)\)

806. *P12059(树的拓扑序,dp)

思考步骤:弱化限制,以后缀 \(\max\) 为核心;对绝对位置的 dp 不可避免,但是非关键的东西转移起来比较轻松。

删除排列的限制为:是拓扑序以及删除 \(u\) 时必须在 \(n-u+1\) 之前。弱化第二个限制,发现只关心后缀 \(\bold{max}\)。从后缀 \(\max\) 的角度入手,启发我们从大到小按照 \(n\to 1\) 填写排列。逐个插入的话,后缀 \(\max\) 当且仅当 \(u\) 放在最后一个位置。再考虑拓扑序的限制:此时 \(u\) 需要放在子树中所有点的后面。对相对位置计数较为困难,考虑直接钦定好绝对位置。状态为 \(f_{i,j,k}\) 表示 \([i,n]\) 中填了 \(j\) 个位置,最后一个位置是全局的 \(k\) 的方案数。

转移的一个问题是如果 \(u\) 不是后缀 \(\max\) 怎么办,此时需要插入到 \([1,k]\) 中剩余的 \(k-j\) 个空位中。发现并没有限制,这个子树内可以自由填写,并且由子树连续,枚举子树中选取了 \(t\) 个数,此时从 \(f_{i+\text{size}_i,j-t,k}\) 转移。预处理每个子树选多少个的拓扑序数量是容易的,在树上背包合并时可以任意归并两个序列,系数是简单的组合数。时间复杂度 \(\mathcal O(n^4)\)

807. qoj14581(树,数位 dp)

考虑令 \(x\to x+f(x)\),这样建成一棵树,查询的就是 \(n\) 个点构成的虚树大小。

先考虑求 \(\text{dep}(x)\),即 \(n=1\) 的情况。将 \(x\) 写成 \(Ax+B\) 的形式,其中 \(A=64,B\in[0,63]\),发现 \(x,x+1,x+2,\cdots\) 一定会被逐个连续遍历到,不会跳过,因此对这个进位的过程进行加速,做数位 dp。以 \(x\) 的低位清空为状态划分,预处理此时 \(x\) 末尾 \(t\) 位都是 \(0\),此时低位值为 \(B\),前面位的 popcount 为 \(v\),第一次进位到第 \(t+1\) 位的值为 \(f_{t,B,v}\),所需步数为 \(g_{t,B,v}\),,转移类似矩阵乘法,这一部分就是 \(\mathcal O(\log^3V)\) 的。最终查询时可以先将 \(x\) 跳到 \(\lfloor\frac{L}{64}\rfloor-1\) 后进行暴力,可以 \(\mathcal O(\log V)\) 求出 \(\text{dep}(x)\)

拓展到求虚树大小。此时对同一棵树的节点按照 \(\text{dfn}\) 排序后减去相邻 \(\text{lca}\) 的深度和。注意到可以求出路径上前一个点,那么钦定顺序是从小到大,求出 \(\text{lca}\) 后就可以比较。直接二分 \(\text{lca}\) 的值然后对于 \(u,v\) 分别求此时的 \(\text{dep}'(v)\),这样是 \(\mathcal O(\log^2V)\) 求出 \(\text{lca}\),往上跳前一个点由低位暴力的过程也是容易的。再考虑排序就是 \(\mathcal O(n\log n\log^2V)\)。注意到二分并不必要,可以直接从低往高一起填位,相同时改成对低位暴力,这部分就降到 \(\mathcal O(\log V)\),同样容易比较 \(\text{dfn}\)。结合排序,时间复杂度 \(\mathcal O(n\log n\log V)\)

808. *P14463(扫描线,中位数)

在考场上要及时发现对 \(f\) 的维护是不可能的!!!

\(x\) 扫描线,固定 \(x\) 时显然转化成 \(-1,1\),区间合法等价于和 \(\ge 0\)。固定 \(l\) 考虑最小合法的 \(r\)\(f_l\),如果对于 \(x\) 存在 \(x<y\) 使得 \(f_y\leq f_x\) 那么 \(x\) 是无效的。随着阈值的增大,每个 \(f_x\) 是单调不降的。注意到一个单调性,如果在阈值 \(A\)\(x\)\(y>x\) 支配掉,那么对更大的阈值 \(B>A\)\(y\) 依旧会保持对 \(x\) 的支配。换而言之,每个位置不被支配的是一段前缀值域(时间)。虽然对 \(f\) 的直接刻画比较困难,注意到我们更加关心支配关系。假设已经求出每个位置的生效时间 \([1,tim_p]\),从询问入手,每个时刻不被支配掉的区间为 \([x,f_x]\),其中 \(f_x\) 是单调的,这样对于 \([l,r]\) 找到最后一个 \(f_p\leq r\) 的位置 \(p\),答案即为 \([l,p]\) 中不被支配掉的点的个数,而一个单点的 \(f\) 是可以求的。

\(tim\):考虑换维。从后往前扫描线序列,维护值域维的信息。考虑在某个阈值下,找到 \(x\) 之后第一个存活点 \(y\)。如果 \(x\sim y-1\) 的和 \(>0\),那么自然合法;否则 \(x\sim y-1\) 的和 \(\leq 0\),此时 \(f_x\)\(y\) 在不考虑长度是合法的,这就要求 \(f_x-y+1<k\),等价于 \(x+k-1\leq f_x<y+k-1\)。限制即 \(\max_{i\in[x+k-1,y+k-2]} s_i>s_{x-1}\)。在扫描线过程中,等价于对序列不断 push_front,因此对于每个阈值维护一下此时的 \(\max s_i=h_i\),相当于一个历史最值,以及当前阈值的 \(v_x=\sum_{x\sim y-1}a_i\)。求支配掉的时间就是找首个 \(h_i<0\wedge v_i<0\) 的位置。\(v<0\) 的是一段后缀,这样直接在这个后缀上线段树二分 \(h_i<0\) 的位置即可求出 \(tim_x\),然后对 \([1,tim_x]\) 做前缀推平历史 \(\max\) 即可。

时间复杂度 \(\mathcal O(n\log n+q\log^2n)\)。单 \(\log\) 还不会。

809. *qoj14579(树上背包,欧拉序,决策单调性)

显然的 dp 做法:\(f_{u,x,y}\) 表示子树 \(u\),在 \(u\) 子树执行了 \(x\) 次操作 II,里面有 \(y\) 个操作 I。由经典复杂度分析,第一维和第三维总和是 \(\mathcal O(nt)\),那么算上卷积部分是 \(\mathcal O(ntk^2)\) 的复杂度。\(t=0\) 可以直接在 dfs 序上考虑,变为插入而不是合并,复杂度 \(\mathcal O(nk)\)

\(t=0\) 的方向进一步拓展,操作 I 更加依赖从下往上,而操作 II 更加依赖从上往下。可以在欧拉序上考虑,即在进入和回溯都记录一次。在进入时决策 II 类贡献(即这个点取了几次),在离开时决策这个点的 I 类贡献。这样依然是插入,但是同时处理了上下贡献的问题。当前在 \(i=l_u\) 时,可以决策:不取贡献并跳到 \(r_u+1\),此时枚举子树 I 类贡献的次数 \(t\),发现一定是贪心确定前 \(t\) 大,容易归并排序合并计算;否则取至少一个点转移到 \(i+1\);当前在 \(i=r_u\) 时讨论一下是否造成 I 类贡献。在 \(l_u\) 处的 II 类需要拆开到这里计算,当 \(l_u\) 处剩余 \(t'\) 个 I 操作时,先决策前 \(c_u-t'\) 个物品,后面的物品留到 \(r_u\) 上决策。写一下转移发现都是单调队列优化,复杂度 \(\mathcal O(nt^2k)\)

结合最开始提到的做法,复杂度 \(\mathcal O(ntk\min(t,k))\),由于 \(t\leq n\) 所以可以分析到时间复杂度 \(\mathcal O((ntk)^{\frac{4}{3}})\)。事实上可以用决策单调性直接把第二部分优化到 \(\mathcal O(ntk\log t)\),也就不需要拼做法了。

810. P14203(双指针,线性数据结构)

枚举绝对众数的值 \(x\),将 \(\neq x\) 的值视为 \(-1\)\(=x\) 的值视为 \(1\)\(x\) 成为绝对众数当且仅当和 \(>0\)。以此有一个 \(+1,-1\) 折线,处理这条折线的前缀和 \(s\),那么 \(f(l,r)=x\) 当且仅当 \(s_r>s_{l-1}\)。这里我们需要只保留到 \(\mathcal O(occ_x)\) 个位置,因为假设 \(occ_x\) 较小,那么折线大部分情况都在掉,此时只有上升的位置附近的点是有效的,我们尝试找到这些有效点的区间,最终区间之间互相独立。显然我们可以计算每个 \(x\) 出现位置对应的 \(s_p\),那么找到上一个 \(\ge s_p\) 的位置 \(q\),将 \([q+1,p]\) 的所有点标记为有效,可以用序列并查集暴力跳来找。最终点数仍是 \(\mathcal O(occ_x)\)

这样转化为对若干区间 \([l,r]\),计算有多少 \(l-1\leq x<y\leq r\) 使得 \(s_x<s_y\wedge\text{mex}(x+1,y)\ge v\)。只有 \(\text{mex}\) 的限制时容易双指针,对于每个 \(l\) 处理出最小合法的 \(F_l=r\),再处理一下每个数的后继,容易做到 \(\mathcal O(len)\) 处理 \(F\)。现在考虑逆序对的限制,注意到相邻 \(s\) 的变化量只有 \(+1,-1\),因此可以暴力维护针对当前位置的逆序对数量,每次移动时重新根据桶的信息算一下相邻位置的变化,这样可以 \(\mathcal O(1)\) 而不是平凡的 \(\mathcal O(\log n)\)。由 \(F\) 的单调性类似做,总时间复杂度 \(\mathcal O(n)\)

811. 20251108 模拟赛

http://oj.daimayuan.top/contest/419

A(凸函数)

每个位置事实上都是可以通过调整变得独立的,令当前第 \(i\) 个位置分配了 \(d_i\) 步,由于每个位置的步数对应代价 \(f(k)\) 是凸的,因此只需要用堆维护变化量最大的一个做调整,时间复杂度 \(\mathcal O(m\log n)\)

C(结构刻画)

考虑对于无序序列的归并,可以提取出 \(A,B\) 各自的前缀 \(\max\),所有非前缀 \(\max\) 的部分一定黏在它前面首个前缀 \(\max\) 上,然后对保留前缀 \(\max\) 的数列 \(A',B'\) 做正常归并即可。

注意到本题前缀 \(\max\) 后面至多带一个元素,也就是说在归并树的叶子节点上,\(\max(x,y)\) 一定成为前缀 \(\max\),但是 \(\min(x,y)\) 可能一直黏在 \(\max(x,y)\) 的后面并永不分离。可以发现,最终结果是:对所有 \(2^{n-1}\) 组相邻叶子节点,对 \(\max(x,y)\) 排序后,令当前序列为 \(P\),逐个决策每一对的 \(\min(x,y)\):以 \(\frac{1}{2}\) 概率插入到 \(P\) 中首个 \(>v\) 的位置之前并加入 \(P\);或者以 \(\frac{1}{2}\) 的概率黏到 \(\max(x,y)\) 之后。容易发现,这样的决策方式与所有交换方案构成双射。

询问形如 \(a_x\) 走到位置 \(y\) 的概率。根据 \(a_x\) 是那对叶子中 \(\max,\min\) 讨论一下,如果是 \(\max\):所有 \(\max(a_l,a_r)<a_x\) 的无影响,那么要考虑 \(\min(a_l,a_r)<a_x<\max(a_l,a_r)\) 的一共有多少个,组合数一下即可。如果是 \(\min\) 首先讨论两种决策,然后类似。可以上树状数组维护这个东西,每次交换只影响至多 \(2\) 对叶子的信息,直接修改即可。时间复杂度 \(\mathcal O((2^n+q)n)\)

D(dp,状压,状态数分析)

直接构造较为困难,考虑 dp。容易想到 \(f_{u,l,r}\) 表示遍历 \(u\) 子树,首位为 \(l\) 末尾为 \(r\) 是否合法,从贪心的角度可以优化为,固定 \(u,l\) 最小合法的 \(r\)\(f_{u,l}\),为了满足单调性,第二维定义换为 \(\ge l\),也就是说保留了一个 \(r\) 的后缀 \(\min\)。注意到每个点的度数都比较小,因此可以直接状压,中间状态为考虑集合 \(S\),起点 \(\ge l\) 最小的终点。直接暴力维护这些集合以及对应的 \(f\) 大概就是 \(\mathcal O(k2^kn^2)\) 的复杂度。

注意到只有一个儿子的点是可以缩掉的。此时,每个点都至少有 \(2\) 个儿子。结论是所有位置被保留的状态数总和是 \(\mathcal O(n\log n)\)。令每个点状态数为 \(g_u\),可以推知 \(g_u\leq (\sum g_v-\max g_v)+\min(\max g_v,\sum g_v-\max g_v)\)。类似于启发式合并即可证明总的状态数是正确的。总复杂度 \(\mathcal O(2^kkn\log n)\),构造方案也是容易的。

to do

ucup season3

PA2024.

posted on 2025-11-08 14:14  nullptr_qwq  阅读(78)  评论(0)    收藏  举报