Gravatar
hsl_beat
积分:294
提交:47 / 76

题意

$n$ 只猫娘,每只猫娘每天要么自己举行了排队,要么会追随自己最好的朋友去参加她要去的派对。


举办的派对有 $3$ 种类型,在每一天晚上都会有一只猫娘举办了某种类型的派对,这只猫娘会一直举行下去直到自己换类型,问每天晚上这三种类型的派对都几只猫娘参加。


思路

首先把猫 $i$ 与自己的朋友连一条有向边,那么整张图就是一个内向基环树。每当一只猫娘举行了派对,这个结点相当于把自己和父亲结点的连边断开了,我们就需要统计每个举办派对的结点子树大小。


如果我们直接对着每一天的修改一个一个做,那么要处理分裂的问题,也能做但是不是很好写,所以我们考虑倒着做。


具体来说,每一天把当前猫娘举办的派对的答案回溯到这只猫娘举办的上一个派对那里(因为这只猫娘从上一个派对到举行当前派对这段时间一直都没变),但是如果这是这只猫娘举办的第一个派对了,那么来她排队里的猫娘和她自己都会跟随她的父亲结点,相当于连上了一条边,可以直接用dsu做,假如当前父亲节点追随的结点举办了派对,那么我们需要把当前结点子树的大小统计进这个派对的类型中。


差点忘了,我们既然从后往前做了,那需要初始化每种类型在最后时刻的人数,可以直接把一直都没举行派对的猫娘直接和她们的父亲节点连起来,然后对于有派对的把对应类型类加上自己子树的大小,然后从后往前一步一步更新当前答案这题做完了。


有一个注意的点在于并查集合并方向要写对,不然只能得 $4$ pts(也可能是我写法问题)。


这题洛谷评蓝是不是太夸张了(


题目4257  [USACO26 JAN G]COW Traversals AAAAAAAAAAAAAAAAAAAAA      2      评论
2026-01-25 22:13:33    
Gravatar
HXF
积分:7223
提交:1326 / 2786

  通常的染色问题是NPC问题,但此题多了m−n<=5的限制,可以将图的大小缩小来解决。将问题拓展为:每条边有两个权值,分别表示两个点同色、不同色时的权值,而一张图染色后的权值就是每条边的权值之积。这样对应原问题时,每条边同色时的权值为0,异色时的权值为1。拓展后的问题可以进行“消点”操作,具体如下:

  • 度数为1的点可以直接删除,并在最终的答案上乘上k−1.

  • 对于度数为2的点,设这个点连向a和b,则可以删除这个点并在a和b之间连一条边,讨论这个点的颜色来决定这个点的权值。具体如下:

    – 如果a和b同色,则有一种情况是这个点与a与b均同色,k−1种情况是这个点与a与b均不同色;

    – 如果a和b不同色,则有k−2种情况是这个点与a与b均不同色,一种情况与a同色,一种情况与b同色。

根据以上规则即可算出新连的边的权值,使得新图与原图等价。

  新图中不会包含度数小于等于2的点,因此新图中的点数n与边数m满足3n≤2m,又因为m−n≤5,所以n≤10且m≤15.

  随后用状态压缩dp进行子集转移即可在O(nm3^n) 的时间内求出新图的权值。


题目4253  染色问题      3      1 条 评论
2026-01-17 14:02:42    
Gravatar
HXF
积分:7223
提交:1326 / 2786


题目3125  《数列》      2      1 条 评论
2026-01-17 13:58:12    
Gravatar
RpUtl
积分:2170
提交:253 / 464

这个题最开始叫根号序列的,因为这个题的三个算法分别是分块,根号分治和根号重构。

$cnt(k)$ 显然是好求的,只需要解决 $\sum [f_i=k]a_i$ 即可。

注意到 $a_i$ 是区间加的,但 $f_i$ 是单点改的,所以可以得到一个 $O(n\sqrt{n})$ 的分块做法。

维护 $s_{i,j},b_{i,j}$ 表示第 $i$ 块中数字 $j$ 的 $a_x$ 之和/个数,对于区间加,散块暴力修改 $a_i$,整块维护每个块的懒标记值 $t_i$,复杂度 $O(\sqrt{n})$。

对于区间询问 $k$,则第 $x$ 块对答案的贡献是 $s_{x,k}+b_{x,k}\times t_x$。复杂度 $O(\sqrt{n})$。

单点修改 $f$ 只需要暴力更改即可,复杂度 $O(1)$,这个过程只要维护好 $b,s$ 两个数组就行。

不难发现这个做法的空间复杂度为 $O(n\sqrt{n})$,但空间限制是 32 MB。考虑优化。

不难发现瓶颈在于 $b,s$,我们对每种数字都记录了 $\sqrt{n}$ 个信息,实际上,这种方法只适用于元素 $f_i$ 出现次数很多的情况,但若一种元素 $f_i$ 出现次数很少,直接暴力遍历也可以解决,考虑阈值分治。

先不考虑修改了 $f_i$ 的情况。若 $cnt(x)\ge \sqrt{n}$,则我们维护元素 $x$ 在 $\sqrt{n}$ 块的信息,反之用 vector 或链表维护元素 $x$ 在序列中的位置。

前者元素种类数不超过 $\sqrt{n}$,所以空间是 $O(n)$,后者显然是 $O(n)$。时间上,传统的分块做法单次查询 $O(\sqrt{n})$,而后者元素的出现次数不超过 $\sqrt{n}$,时间也是 $O(\sqrt{n})$。

考虑加入修改 $f_i$ 的操作,不难发现可能存在元素从 $cnt(x)$ 从 $\ge \sqrt{n}$ 变成 $< \sqrt{n}$。考虑定期重构,对操作分块,每 $\sqrt{n}$ 次操作就重新根号分治做初始化。

对于修改了 $f_i$ 的位置 $i$,在下一次重构前,我们不用分块也不用 vector 维护,而是把他们专门放到一个 vector 里,统计他们对每个询问的贡献,因为定期重构,这个 vector 内元素个数不超过 $\sqrt{n}$。

这一部分要注意把修改了 $f_i$ 的位置 $i$ 从原数据结构中删除,分块的直接删掉贡献,vector 可以用懒惰删除,最后总复杂度就是 $O(n\sqrt n)$。


题目4242  团子大家族      3      评论
2026-01-03 16:00:03    
Gravatar
HXF
积分:7223
提交:1326 / 2786

题目4245  字符串游戲      2      评论
2026-01-03 14:38:19    
Gravatar
RpUtl
积分:2170
提交:253 / 464


先考虑 $O(nq)$ 做法。枚举每个点为根去 DFS 做 dp。

不难发现两个相邻的点不能操作二,所以状态要设 $f_{i,2}$ 表示点 $i$ 操作二,把子树的边覆盖完的最小操作。

若一个点不进行操作二,则他到子节点需要用操作一来覆盖,而一个操作一可能端点在两个儿子。考虑先把这个操作一的链拆开,然后从儿子向上合并时去匹配。设 $f_{i,1},f_{i,0}$ 表示点 $i$ 进行操作二,覆盖后子树内留下一个到儿子的操作一半条链没有匹配或全部匹配完。

然后考虑 dp 转移,分类讨论即可:

$$f'_{x,0}\gets \min(f_{x,0}+f_{y,2},f_{x,1}+f_{y,0},f_{x,1}+f_{y,1}-1)$$

$$f'_{x,1}\gets \min(f_{x,1}+f_{y,2},f_{x,0}+f_{y,1},f_{x,0}+f_{y,0}+1)$$

$$f'_{x,2}\gets f_{x,2}+\min(f_{y,0},f_{y,1})$$

然后直接转移就可以,复杂度为 $O(nq)$。

考虑换根出答案?但是这个贡献形式比较难拆开,考虑用矩阵描述 dp 的转移,这样做前缀后缀的转移就转化为求矩阵前缀后缀积了,本来矩阵乘法需要严格控制顺序,但这个东西先合并那个子节点无所谓,所以瞎做就行。

复杂度为 $O(nV^3)$,其中 $V=3$。



题目4078  路径覆盖 AAAAAAAAAA      4      评论
2025-12-21 11:38:22