🍕🏠🌋 当前时间是:

 

2025.3

我会把近期(准备)做的题在博客里记录下来。

3.9

P4690 [Ynoi Easy Round 2016] 镜中的昆虫

区间数颜色可以写成二维数点。

区间赋值可以用颜色段均摊做掉。

用 CDQ 分治和树状数组可以做到 2log。

3.10

P11831 [省选联考 2025] 追忆

由于需要可达性统计,所以复杂度至少是 \(O(\dfrac{nm}{w})\) 的。

考虑算点对询问的贡献,可以操作分块,提取出 \(O(T)\) 个关键点,然后一个询问限制都可以用 \(O(T)\) 大小的 bitset 表达出来。

还需要每块内暴力算询问点和被修改的点的贡献。

复杂度是 \(O(\dfrac{q}{T}\dfrac{(n+m)T}{w}+qT)\) 的,由于 Bitset 常数小,实际 T 取大一些跑得快。

20250310模拟赛 T2

唐题。直接 ddp。

3.11

20250310模拟赛 T1

这个题必须把做法想清楚再写。QAQ

枚举 \(x\),我们要求 \(f(x)\bmod \dfrac{x^m-1}{x-1} = 0\),把这个形式变成 \(f(x)\cdot (x-1)\bmod (x^m-1)=0\),因为这样更方便判断倍数。

然后考虑模 \((x^m-1)\) 的意义,直接模拟,再把系数的绝对值放到 \([0,x)\) 的范围内,这样就好 check 了。

模拟过程中每次给系数和的绝对值减去至少 \(x\),这样只会操作 \(O(\dfrac{n}{x})\) 次(系数总和是 \(O(n)\) 的)。

挺不好写的,需要撤销一堆操作。

复杂度是 2log。

20250224模拟赛 T1

考虑极小正交子集的判定:任意删去一个数,剩下的数与和不为 0。也即选的每个数都存在一位 0,其他选的数这一位都是 0。

直接压下来每一位的状态(有三种:全 1;大于一个 0;1 个 0),状态量是贝尔数的,不可接受。

考虑类似插头 dp,每一位有四种状态:全 1;有一个 0 且是某个选出来数的独特的位;要求有大于 1 个 0;随便填。

转移的时候需要枚举钦定为独特位置的子集,复杂度应该是 \(O(5^ww)\) 的。

但是我们可以发现对于一个选上的数,只需要考虑它最终状态下第一位(或者任意可以找到映射的位)独特的位置就可以计数了。

这样转移可以更快,复杂度是 \(O(Tn4^ww)\) 的,手写哈希表可以过掉。(由于 \(n\) 较小,状态量不太跑得满,不知道可不可以 hack)

题解给了种容斥的做法,还没太看懂怎么把状态降到 \(O(3^w)\) 的。

PKUWC2025 D1T1

ANIG 给我看的。

感觉不是题。

首先要想到建图,就变成了对于大小为 \(a+b\) 的图,不存在一个大小为 \(a\) 的子集,使得子集内两两没有连边,也就是连最少的边使最大独立集小于 \(a\)

不知道为啥,每个连通块是完全图的时候最优,均分就行了。

补题补了将近一天,唐完了。

3.12

20250312模拟赛T1(>.<)

最终的最短路径不能包含输入的子串,因此想到对输入串建 AC 自动机。

直接的想法是记录 \(f_{i,j}\) 表示到第 \(i\) 个点并匹配到 AC 自动机上第 \(j\) 个点的最短路。

而这个状态量实际是 \(O(n+L)\) 的,可以接受。

现在问题在于建 AC 自动机和转移。

由于字符集非常大,需要使用主席树维护出边集合。

暴力转移是平方的,因为一个点可以度数很大而且对应 AC 自动机上很多点。

转移有两类:转移后失配和转移后不失配。

对于第二种,直接在主席树上遍历所有出边,并标记已经遍历的边,保证每个主席树叶子只遍历一次;

对于第一种,需要额外更新原图该点的出边保证正确性,用一些手法可以把复杂度均摊正确。(upd:和第二种转移类似,在主席树上做)

最后是 1log 的。

我赛时不会写第一种转移,瞎乱搞了一些转移跑过去了。

20250312模拟赛T2(在路上)

考虑如何 check 一个点 \(x\) 是否是重心。

直接随点 \(y\),接着 \(O(n)\) 问出每个点和 \(y\) 是否在 \(x\) 同一个子树内。

如果 \(y\) 所在的子树大小超过 \(n\) 的一半,就可以判定为非重心。

否则继续做。

但是菊花就能卡掉。

首先考虑如何更快地 check 菊花中点是否为重心。

由于非重心有大小超过 \(n\) 一半的重子树,直接随 \(O(1)\) 次就能随到,所以设个阈值 \(v\),随机次数超过了就判定为重心,正确率是指数级的。

然后要考虑优先找到菊花中点:可以预先随一些三元组做询问,对它们中间的点权值加 1,然后按照权值从大到小 check。

这样菊花就是期望 \(O(nv)\) 次询问了。

再加个剪枝:轻子树内的点一定不是重心,标记上不再 check。

这样随机的树看上去就是期望 \(O(n\log n)\) 次询问了,我也不知道为啥。

可以跑过除了最后一档和链。

再加个剪枝:每次 check 把轻子树内的点合并到 \(x\) 上并把轻子树内的点删掉,以后 check 的时候忽略被删的点并认为 \(x\) 贡献的子树大小是合并到它上面的点的数量。

这样看上去对完了,调参后可以跑过除了链的所有数据(链那一档范围较最后一档数据更大)。

给链拼一个类似最后一个剪枝的随机二分即可(这部分的询问次数是期望 \(O(n)\) 的)。

题解给的做法是随路径,\(O(1)\) 次就可以找到一条经过重心的路径,再套链的做法 check。

3.13

20250312模拟赛T3(相等树链)

对第一棵树点分治,计算经过分治中心 \(x\) 的合法路径个数。

如果路径 \((p,q)\) 合法,那么路径 \((p,x)\)\((x,q)\) 在第二棵树上各自形成一段路径(可以不连续),并且 \((p,q)\) 在第二棵树上对应路径的端点源自 \((p,x)\)\((x,q)\) 在第二棵树上对应的端点。

还要求路径上点集合相同,对端点的几种情况分讨,使用 xor hash 拆贡献判断,可以放到哈希表里面。

需要注意有选出来的端点在第二棵树上 \(x\) 同一子树内的 case,这是不合法的,应当特判,需要求树上一段路经的第二个点。

如果写 \(O(1)\) k 级祖先或离线可以 1log。

但是我直接写的倍增,常数很小,也是可以跑的。

具体细节较多,不好写。

20250313模拟赛 T1

直接做是 2log 的,由于树状数组常数较小,可以比较快地跑过去。

离线转置一下应该可以 1log。

20250313模拟赛 T2

赛时判挂了个 corner case。

大部分情况下 \(k\) 可以和 \(n^2-k\)\(\min\) 更方便构造(除了 \(n\) 是奇数且 \(k\) 模 4 余 2 的情况,把 \(k\) 变成 \(n^2-k\) 似乎更好做)

如果 \(n\) 是偶数,对 \(k\) 分讨:

  • \(k\) 是奇数,显然无解。

  • \(k\) 是 4 的倍数,直接 \(2\times 2\) 地填。

  • 否则可以构造缺一对角的环形 1。

如果 \(n\) 是奇数也是类似的。

比较特别的是 \(k<2n-2\) 时,构造为:先用 1 把左上边界填满,再把左上某个正方形区域的 1 抹去,换成对角线 1。

以及 \(k\) 模 4 余 3 的时候:左上 \(3\times 3\) 的正方形填对角线,再把左上边界剩下部分填 \(1\times 2\),中间的空白填 \(2\times 2\)

需要特判一些 corner case。

直接分讨构造还是挺一坨的。QAQ

3.14

P8511 [Ynoi Easy Round 2021] TEST_68

直接 dsu on tree + trie 是 2log 的,肯定过不去。

一个很牛的 trick 是先毛估估一下,发现不少点的答案都是全局异或最大点对,只有最多两条链上可能不是,跑两遍链的做法就行了。

P6072 『MdOI R1』Path

答案拆成每个点子树外和子树内的最大点对的贡献,第一部分就是上一题。

子树内的的最大异或对似乎不能 1log,但是由于这题让和最大,只需要考虑全局最大点对和根的路径直接相连的节点的子树就行了。

关键就是去考察一些题目性质,而不是尝试把一个经典问题做到更优复杂度。

P10218 [省选联考 2024] 魔法手杖

二分答案,然后问题变成找一个大于 \(mid-min_a\)\(x\),使所有异或 \(x\) 后小于 \(mid\) 的值的代价之和尽可能小。

这是可以直接在 trie 上做的。

复杂度是 2log。

1log 咋做啊?

20250314模拟赛 T1

题意是搜出序列的字典序前 \(k\) 小的子序列的哈希值。

暴力 pq 做复杂度是指数的,考虑把搜索树三度化,可以做到平方乘 log,瓶颈在比较。

数据太唐了,赛时写了个假的 dfs 把最后一档跑过去。

正解可能是某种顺序 dfs 规避比较?等我补题。

20250314模拟赛 T2

复杂度线性,36 秒时限被卡常,无敌了。

考虑 \(len1,len2>m\) 的时候,贡献只有可能从 \(A\)\(B\)、跨过 \(AA,AB,BA,BB\) 中点这几种情况中产生。

于是每次询问可以把先把询问串的每种循环同构串插入哈希表,再把 \(len1,len2\) 递推到最小的大于 \(m\) 的时候,然后把系数用矩乘算出来,每种情况可以哈希算出来贡献。

复杂度是 \(O(Qlen+\sum m)\) 的。

谴责数据造挂QAQ。

3.15

20250315模拟赛 T1

\(b\) 序列是 popcount 的奇偶性。

只有询问可以建 st 表,然后在线段树上把询问区间划分成 2 的整次幂长度统计,复杂度是 1log 的。

带修可以加上操作分块,攒满 \(B\) 个操作就重构,复杂度可以做到 \(O(n\sqrt{n\log n})\),暴力部分常数较小,可以直接跑。

不知道有没有更快的做法。

upd:直接分块维护可以做到单根号。

3.16

20250315模拟赛 T2

先把题意转化成数每个前缀的 2143 的四元组。

从小到大扫描值域,对于 \(a_i\),要数以 \(i\) 为第四个元素的组数。

直接统计前面的 214 是不太容易的,但是可以变成 小小大-124。

而 124 是容易统计的。

线段树维护即可,复杂度 1log。

感觉赛时没有想到扫描值域糖丸了。

20250315模拟赛 T3

考虑一个点会对后面哪个点产生影响,这样的结构构成一棵树(赛时我考虑的是反的边,误以为是有向图,然后就做不下去了QAQ)。

考察树的形态和操作的性质,可以发现树不存在交叉的边,所以存在一种重标号方式,把操作区间变成 dfn 区间。

问题就转化成给一棵树,每次操作翻转 dfn 区间里的点的颜色或查询这些点构成的子树(森林)的答案。

考虑在线段树上做这个东西,问题在于如何合并两个区间。

可以发现,左边对右边没有贡献,而右边的区间对左边的贡献是使一条链合法,可以找出来。

具体细节上可以观察到:dfn 区间内的点构成的子树挂在一条链下面(根节点除外)。稍微分讨一下就好了,需要 lca。

复杂度是 1log。

20250314模拟赛 T3

感觉放在 T3 很搞笑,但是不太容易注意到。

拆一下贡献,发现深度和就是祖先-子孙点对个数,于是变成了数前缀有多少个相等的子串对,sam 上随便做一下就行了。

3.17

ARC193D

CF2077F

CF2077G

20250317模拟赛T1

先做只有偶数和只有奇数的情况:

除了 \(n=1\) 外,偶数要求给每个数赋正负号,并且正负号都出现过。

对于奇数,如果个数是偶数,要求正负号数量相等(我不知道为啥,这是手玩猜的),个数是奇数的话删一个数不影响答案。

把两个拼起来,需要判一下可能的偶数全正或全负的 case。

反正细节有点多。

20250317模拟赛T2

写出来平方的 dp,状态记录子树内哪个点作为插头。

使用李超树优化。

3.18

20250317模拟赛T3

暴力就是建出 AC 自动机,消元解出每个点随机游走的期望步数。

接下来分两个部分:优化消元和处理多次询问。

对于 trie 上一个点 \(x\),如果 \(x\) 的出度是 1,那么它唯一的儿子可以被深度不超过 \(x\) 的点表示,最后发现相当于可以缩掉直链,这样图上就只有 \(O(n)\) 个点了。感觉拿关键点表达其他点这种 trick 很有用啊!

多次询问加个颜色段均摊和倍增就行了。

难度比较大的题,细节也很多QAQ。

20250318模拟赛T1(P11918 [PA 2025] 考试 / Egzamin)

暴力就是把 \(p\) 降序排序,然后对每个前缀背包算答案取 \(\max\)

由切尔诺夫定理相关内容可知保留期望值附近 \(O(\sqrt{-n\log \epsilon})\) 个点值就能算出精度范围内的答案。

实际实现的时候也可以设置阈值,把概率小于阈值的状态扔掉,复杂度是差不多的。

CF2061I

据说套用这个题的做法可以 2log 严格做上一题。没有做这个题。

20250318模拟赛T2(P11928 [PA 2025] 子序列 / Podciągi)

正解做法是直接摁在线段树上维护 \((a,b)\) 开头结尾的不同子序列数量,可以直接做到 \(O(qm^4\log n)\),再注意到合并信息时的转移可以拆成两步矩阵乘法就能做到 \(O(qm^3\log n)\)

我赛时的做法是把答案容斥为本质不同子序列数-只出现一次的子序列个数,前半部分是好用 ddp 维护的,后半部分需要注意到单点修改只会改变 \(O(m)\) 个位置的转移矩阵,找出来暴力更新即可,复杂度是 \(O(qm^4\log n)\),似乎不太好去掉一个 \(m\),但是瓶颈在矩阵乘法,常数比较小,不卡常也能跑过去。

3.19

20250318模拟赛T3(P11924 [PA 2025] 贪婪大盗 / Piracka Chciwość)

考虑暴力就是从后往前做,每次排序选代价较小的一半,总和不够就只能让自己扔到海里。然后赛时没调出来暴力然后赛时没调出来暴力然后赛时没调出来暴力然后赛时没调出来暴力然后赛时没调出来暴力然后赛时没调出来暴力

然后考虑用 ds 优化这个过程:

直接维护序列肯定是没道理的。但是由于值域比较小,可以猜测对于每种 \(a\) 和当前的钱数,记录这类人的位置。

大部分人的钱数不会超过两倍的最大值(可以打表或观察大样例看出),这是因为每次都有大约一半人是没有分到钱的。

除去当前做决策的人,其他人的钱数都是其 \(a\) 的倍数,故状态只有 \(O(a\log a)\) 个。

使用动开线段树维护,那么需要在 \(\text{maxd}\) 棵线段树上二分,然后分裂出后缀,其他还需要一些合并操作,复杂度均摊下来是对的。

所以复杂度是 \(O(na\log a+\text{maxd}n\log n)\)

不好写的。

被卡常了,先就这吧。

20250319模拟赛 T1

首先容易猜到答案是 0。

假设已经钦定了两个物品要切,并且剩下部分已经分好,那么可以解方程得到两个物品的切割系数使得答案为 0,check 切割系数是不是在 \([0,1]\) 里面。

然后不知道为啥直接随两个物品并把剩下的贪心分配可以过掉几乎所有数据。

再把贪心加个随机交换,多交几次就过了??

但是当密度全部相同时方程会无解,小样例就有这种 case。

还没有补正解。

update :

正解非常有道理,遇到这种实数权值的构造题可以往函数连续性上考虑。

考虑把所有物品按照密度从小到大拍到数轴上,一个物品占据 \(v_i\) 的长度。

假设答案是 0,那么我们就是要找到一种方案,使得一个集合内的体积和为 \(\dfrac{\sum v_i}{2}\),质量和为 \(\dfrac{\sum m_i}{2}\)

接下来不断维护长度为 \(\dfrac{\sum v_i}{2}\) 的区间,初始是 \([0,\dfrac{\sum v_i}{2}]\),最终是 \([\dfrac{\sum v_i}{2},\sum v_i]\)

由于按密度排序,初始区间内的质量总和是小于等于 \(\dfrac{\sum m_i}{2}\) 的,而结束的时候质量总和大于等于 \(\dfrac{\sum m_i}{2}\)(可以反证)。

由于质量是连续变化的,所以过程中一定存在一个区间满足其长度为 \(\dfrac{\sum v_i}{2}\) 且质量和为 \(\dfrac{\sum m_i}{2}\),而区间保证了不会切割超过两个物品。双指针找到它就行了。

20250319模拟赛 T2

对着平方的 dp 做线段树合并。

信息可以写成向量,转移是矩阵,这样比较好想。

3.20

今天模拟赛很爆。

20250320模拟赛T2

考虑如何判断一个区间是否是好的:

  • 它的 \(B\) 最大子段和等于其总和。

  • \(A\) 序列剩余部分最大子段和小于等于其总和。

  • \(A\) 序列左边最大后缀和小于等于 0,右边最大前缀和小于等于 0。

对于询问,大概的想法应该是拆贡献,扫描一个端点,维护另一个端点好区间的历史和。

下面逐步拆分判定条件:

\(B\) 前缀和序列当前前缀的后缀最小值位置,再维护后缀最大值找到上一个大于当前前缀和的位置(相当于找到合法区间左端点),满足第一个条件,使用单调栈就只有 \(O(1)\) 的。

只对于右边部分 \(A\) 序列最大前缀和小于等于 0 的右端点加入历史和,并只算左边部分 \(A\) 序列最大后缀和小于等于 0 的左端点的贡献,可以满足第三个条件。

对于第二个条件,可以发现,满足条件的左端点在一个区间内,可以直接二分出来区间的位置。

使用矩阵维护历史和即可。

复杂度是 1log。

3.22

线性的树上期望 dp 做法

不会这个 trick,被 T1 薄纱了。

对于树上这种形式的方程:\(f_{u}=\sum w_{u,v}f_v\)\(v\)\(u\) 在树上相邻,下略),并且根节点 \(f\) 值确定,可以快速求出每个点的 \(f\) 值。

做法就是设 \(f_u=k_uf_{fa}+c_u\),也就是表示成父亲的 \(f\) 值乘系数再加上一些东西的形式。

接着可以推出:\(f_{u}=w_{u,fa}f_{fa}+\sum\limits_{v\neq fa} w_{u,v}(g_vf_u+c_v)\)

整理一下可以得到: \(f_{u}=\dfrac{w_{u,fa}}{1-\sum\limits_{v\neq fa} w_{u,v}g_v}f_{fa}+\dfrac{1+\sum\limits_{v\neq fa} w_{u,v}c_v}{1-\sum\limits_{v\neq fa} w_{u,v}g_v}\)

所以从叶子往根 dfs 一遍就能求出所有点的 \(g,c\) 值了,再推回去就能得到答案。

特别地,当边权为 \(w_{u,v}=\dfrac{1}{deg_u}\) 时,容易归纳出 \(g_u=1,c_u=\sum\limits_{v\in subtree(u)} deg_{v}\),也就是说树上每个点随机游走到根的期望步数是整数。

20250322模拟赛 T1

使用上面的 trick,把问题变成:树上随机删 \(k\) 条边,求 \(s\) 点在原树上所有祖先(包括自己,不包括根)在现在这棵树上的子树度数和的期望。

拆贡献:考虑每个点贡献给 \(s\) 的哪些祖先,想清楚后可以写出平方的式子。

发现形如 \(\sum\limits_{0\leq i\leq r} \dbinom{A-i}{B}i\)

可以用组合数递推式构造抵消推导:

由于 \(\dbinom{A-i}{B}i=(\dbinom{A-i+1}{B+1}-\dbinom{A-i}{B+1})i\)

原式即为 \(\sum \dbinom{A-i+1}{B+1}(i-1)-\sum \dbinom{A-i}{B+1}i + \sum\dbinom{A-i+1}{B+1}\)

前两项经过抵消只剩 \(O(1)\) 项,最后一项再使用一次递推式可以变成 \(O(1)\) 项。

\(\sum \dbinom{A-i}{B} i^k\) 按照这个做法应该也是可以 \(O(k^3)\) 求的。(本质不同的有 \(O(k^2)\) 项,每项的系数需要 \(O(k)\) 计算)

3.24

20250320模拟赛T1(P11923 [PA 2025] 砖块收集 / Zbieranie klocków)

很牛的题,被薄纱了。

手玩一些形态可以发现:

处在 2*2 积木块内的积木不能移除,通过不能直接被删的积木斜着两端连到在 2*2 块内的积木的积木也不能移除。

然后需要找个好做的充要条件。

可以把处在 2*2 积木块内的积木称作 C 类点,可以直接被删掉的积木称作 A 类点,其他点称为 B 类点。

C 类点一定不被删,B 类点能不被删则要求它处在的两条斜率绝对值为 1 的直线上至少有一条(事实上最多有一条),满足它处在的极长 B 类点区间两端是 C 类点。

使用线段树维护斜线信息,每次单点修改只会改变不超过 9 个点的类型。

复杂度是 1log 的。

20250319模拟赛T3

首先,这个操作放在序列上就是交换前缀和数组的相邻两项,这我咋能注意到啊啊??

在环上的话可以手玩一下,发现就是把序列自己拼接无限次,得到前缀和数组,每次操作 \(i\) 会交换模 \(n\)\(i\) 的相邻项。

如果整个环的总和小于等于零,那么只有数全为 0 的时候有解,否则可以发现是无解的。

所以可以认为序列总和大于 0。

那么想要把整个序列排成有序的,就要求逆序对数为 0,由于每次操作是操作一个剩余系,所以对于每种 \(i\),可以算出模 \(n\)\(i\) 的位置对答案的贡献就是前面比它大的数的最大值。

由于序列总和大于 0,所以这个东西是有限的。

可以得到位置 \(i\) 的贡献是 \(\sum\limits_{x<i,s_x>s_i} \lfloor\dfrac{s_x-s_i-1}{s_n}+1\rfloor+\sum\limits_{x>i,s_x>s_i} \lfloor\dfrac{s_x-s_i-1}{s_n}\rfloor\),其中 \(s\) 是这个环任取起点前缀和的数组。

\(s_x\) 除以 \(s_n\) 的商和余数讨论,二维数点,可以 1log 解决。

20250322模拟赛T3

把一个排列变成单峰的最小相邻交换步数。

难蚌,一年前听 ANIG 给我说过这个原题,但这次没想出来咋做:https://qoj.ac/problem/8341

考虑对于一个最终的序列,如何计算答案:

使用原序列中数的位置在最终序列的逆序对数量计算答案。

从大到小插入每个数,那么它只能放到最前面或最后面。

如果放到最前面,那么新产生的逆序对数是位置比它靠前的且比它大的数,放在最后是对称的。

因此发现每个数的贡献是独立的,是前面比它大的数的个数和后面比它大的个数的最小值,求和就是最小步数。

搬过来的题变成了对每个前缀算答案,线段树做一下就行了。

P7880 [Ynoi2006] rldcot

和这个题类似的 trick 被称为“支配对”。

枚举每个点,考虑什么(非平凡)情况下它会被作为 LCA。

要求其不同的两个子树内有两点 \(a,b\) 满足 \(l\leq a,b\leq r\)

容易发现,对于一个 \(a\),只有比它小的第一个 \(b\) 和比它大的第一个 \(b\) 是有用的。

而且这些点对是对称的,所以可以 dsu on tree,忽略掉重子树的 \(a\),对所有轻子树的 \(a\) 算出其最优的两个 \(b\)

这样会找出来 \(O(n\log n)\) 个数对,对它们做二维数点就行了。

ARC195E

对于这类“随父亲”,求 LCA 深度的期望的问题,有这样的 trick:

对于 \(u<v\),先把 \(v\) 往上跳,那么当 \(v\) 第一次跳到 \(\leq u\) 的点时,它是等概率跳到 \(1\)\(u\) 号点的。

然后就能递归到子问题,可以 dp 算出来答案。

顺带的一个观察是 \(u,v\) 的 LCA 的深度的期望和 \(v\) 无关。

3.25

20250325模拟赛 T1

先来考虑树的做法:

对于一个点,它可以向子树内伸出两条权值分别严格递增、递减的路径,而这两条路径再往下就不能分出更多严格单调的路径了。

整理一下发现问题就是,找出树上一条路径,使得路径上每个点连接的子树大小平方和最小,可以斜率优化解决。

对于图,可以发现环上所有点权值必然相等,所以边双缩成树就可以了。

20250325模拟赛 T3

超级底力题,raft

3.26

20250326 T1

线段树维护矩阵转移板子。

20250326 T2

又随机化爆过去了QAQ

20250326 T3

对四个点的独立集方案数容斥,发现要做的是统计十种形态的子图的数量。

可以使用三元环四元环计数做完,非常多细节。

补一下四元环计数做法:

度数小的点往度数大(度数指偏序关系,度数相同的比较节点编号就可以)的点连边。枚举四元环中度数最小的点 \(u\),枚举其在原图上的邻接点 \(v\),并枚举 \(v\)新图上的出边 \((u,t)\),要求 \(t\)\(u\) 度数大,统计 \(t\) 上的标记,再对 \(t\) 打上一个标记。
复杂度:如果 \(v\) 度数小于 \(\sqrt{m}\),这部分贡献不超过 \(m\sqrt{m}\);否则 \(v\) 在新图上的出边不超过 \(\sqrt{m}\) 条,这部分贡献也是 \(m\sqrt{m}\) 的。

CF985G Team Players

异或

给定 \(n\) 个非负整数,每个数有颜色。再给 \(m\) 次操作,每次修改一个数的颜色。每次修改完问两个颜色不同的数的异或值最小是多少。值域 \(2^{30}-1\),强制在线。

感觉很唐,但反直觉。

考虑在 trie 上做这个东西,每次修改完 pushup 更新子树的答案。

信息合并时,首先要继承两个子树各自的最小答案,然后要考虑从两个子树里各选一个颜色不同的数出来的最小异或值。

注意到如果一颗子树内有超过一种颜色,这是不优的,可以不更新。

那么只有两子树颜色相同和不同的 case 了。

相同是不用更新的,不同的 case 看上去不好做,但是因为子树的形态是确定的,可以预处理出来。

3.27

怎么 Day2 又爆了啊啊啊

T1

不会 flow 啊。

这题是有比较简单的建模的:

考虑每个格子:要么一条边都不连,要么横向竖向各连一条边。

那么一个格子可以拆成两个点,分别表示横向和竖向连边,那么每个竖向点和该格子上下的相邻各自匹配,横向同理。

还要考虑格子不连边的情况,这时候可以认为横点和竖点匹配,费用为 0。

可以发现建出来的是二分图,跑最小费用最大流就行了。

T2

考虑把条件改写一下,记一个点 \(u\) 的权值为 \(\max \limits_{x} d_x-dis(u,x)\)

那么 \((i,j)\) 合法相当于 \(i,j\) 路径上存在一点 \(x\) 使得 \(w_x\ge dis(x,i)\)\(w_x\ge dis(x,j)\)

分治中心两侧都有合法的 \(x\) 会算重啊??

后面咋做啊啊啊?

upd:

现在会了,对于分治重心 \(r\),把 \(dis(i,r),dis(j,r)\leq w_r\)\((i,j)\) 贡献单独算,就不会有这种 case 了。

证明:
\(x\)\((i,r)\) 的路径上,\(y\)\((j,r)\) 路径上,如果不满足这个条件并存在这种 case,那么要 \(w_x-dis(x,r)<dis(r,i),w_y-dis(y,r)<dis(r,i)\)\(w_x>dis(x,r)+dis(j,r),w_y>dis(y,r)+dis(i,r)\) 同时成立,不等式相加可以发现这是不可能的。

感觉很难。

其余部分用树状数组可以做到 2log,也可以单调队列做到 1log。

\(w_x\) 可以在点分治的时候顺便处理出来。

P10785 [NOI2024] 集合

考虑两个区间同构的充要条件。

可以观察到,如果每种值的数出现的位置的集合构成的集合相同,那么两个区间同构。

使用 \((+,\text{xor})\) 哈希和双指针找出每个右端点的最长同构区间即可。

3.28

还有人比赛没结束,30 号晚上再写。

upd:

T1

考虑最终的子序列在 A 序列中的三段的分界点,枚举 01 和 2 的分节点,答案就是二维数点了。

需要做的操作是单点 chkmax,前缀最值,可以使用树状数组,常数很小可以跑过去。

细节略有点多。

T2

据说是费用流线性规划对偶板子,但是我不会。

T3

有人不会写后缀数组,认为 SAM 线性建后缀树可以平替 SA,被这个题 256MiB 狠狠制裁了。

感觉这个题的结论很有意思啊。

先想对于一个串 \(k=2\) 的做法:一定是选字典序小于整个串的后缀为界划分。

接下来对于更大的 \(k\) 可以讨论一些情况:

如果这个后缀的字典序已经比其之前的子串小了,那么划分可以停下来了,因为后面不管怎么划,最大字典序都是前面的子串。

否则归纳可知前面划分的子串是这个后缀的前缀。

也就是说,最终的结构是一段具有周期的串加上一个字典序更小的后缀。

\(k\) 和周期出现次数讨论,尽量均分即可。

3.30

AGC071A

感觉很有趣味。

考虑区间 dp,\(f_{l,r,v}\) 表示区间 \([l,r]\) 整体异或上 \(v\) 之后的答案,容易发现一个区间的 \(v\) 只取值于 \(O(n^2)\) 个区间,可以得到 \(O(n^5)\) 的做法。

接着来观察这个过程的性质:一个很关键的事情是异或是可以抵消的,如果 \([l,r]\) 分裂后有一个长度为奇数的区间 \([l,k]\),那么另一个区间 \([k+1,r]\)\([l,r]\) 之上受到的影响就被清空了,其当前的整体只是异或上那个长度为奇数的区间 \([l,k]\) 的异或和。

所以可以建出来分裂过程的线段树,一个叶子节点最终的取值就是向上跳,直到一个区间 \([l,r]\) 的兄弟节点长度为奇数,其取值就是 \([l,r]\) 的异或和,特殊地,如果不存在这样的 \([l,r]\) 其取值就是整个初始序列的异或和,这样的叶子节点在初始序列长度为奇数时恰有一个,称为关键点。

对这个就可以 dp 了,如果当前的 dp 区间 \([l,r]\) 长度为奇数,那么要记录该区间选一个关键点之后的和的最小值(不包含关键点);如果长度是偶数,就记录该区间的答案。

转移:

如果 \([l,r]\) 长度是偶数,若分裂为两个长度为奇数的区间,就把两个区间的 dp 值加起来,再加上两个关键点的贡献(2 倍的当前区间异或和),若分裂为两个长度为偶数的区间,就直接把两个区间的 dp 值加起来,这是因为再往下分一定会出现分出两个奇数区间的情况,上面的区间就无影响了。

如果 \([l,r]\) 长度为奇数,一定是分裂成两个长度分别为奇数、偶数的区间,对于偶数的区间,其贡献是其 dp 值,原因和上一种 case 相同,对于奇数的区间,其贡献是 dp 值加上 \([l,r]\) 的异或和。

复杂度是 \(O(n^3)\),常数很小。

posted @ 2025-03-10 14:42  zzafanti  阅读(122)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end