Skip to content

202408 集训测试 笔记

没写的题意思是暑假没做出来,没什么时间补了。

Day1A

简要题意:tt104)个 nn300)位字符串,每次操作选中一个字符串相邻的两个字母,将其中一个变为字母表的前一个字母,另一个变为字母表的后一个字母,a 不能向前,z 不能向后,对于每个字符串,它能变化出多少种不同的字符串?

解析:假设 a 的 “ASCII 码”是 1,发现每次操作后,那个字符串的 ASCII 码总和不变,设一开始字符串的总和为 S,那么问题变成求:

a1+a2++an=S,1ai26

的方案数。

DP 求即可,设 fi,j 表示处理到第 i 位,前面总 ASCII 码为 j 的方案数,答案即为 fn,min(cntd,cntu)cntd 表示每一位向前调的总和,cntu 表示每一位向后调的总和。

时间复杂度 O(262n2+Tn)

Day1B CF82D Two out of Three

解析:发现在第 i 轮中,总是在 2×i2×i+1 和上一轮中剩下的 j 里选 2 个,因此,设 fi,j 表示第 i 轮剩下 j 的最小代价。

fi,j=fi1,j+max(a2×i,a2×i+1)fi,2×i=fi1,j+max(a2×i+1,aj)fi,2×i+1=fi1,j+max(a2×i,aj)

时间复杂度 O(n2)

Day1C

简要题意:求 {1,2,,n105} 两两之间商不为 23 的子集个数。

解析:如果考虑选择 p,那么在得到这样一张表格图:

12345
p3p9p27p
2p6p18p54p
4p12p36p108p

左右相邻的不能选,上下相邻的不能选。

即使 p=1,最多 1117 行。

故用状压 DP fi,s 表示第 i 行选中的数的集合是 s 的方案数。

对于每个没有出现过的 p 都要做一次 DP,每次求出的答案相乘。

时间复杂度 O(plog2(n)×2log3(n))p[1,n] 间质数的个数。

Day2A

简要题意:n100 歌瓶子,每个瓶子里最多能放 bi100 个物品,每个瓶子目前里有 ai 个物品,将所有物品移动到个数最少的瓶子里,瓶子个数最少是多少?在此条件下,最少要移动多少个物品?

解析:设 sum 表示物品总量,fi 表示装 i 个物品需要多少个瓶子,gi 表示在 fi 的条件下,选中的瓶子里最多能有多少个物品。

fj=min{fjbi+1}gj=maxfj=fjbi+1{(gjbi+ai)}

答案在 i[sum,1002] 中找到最小的 fi,并记录当 fi 最小时 gi 的最大值 mx,用 summx 就是移动次数。

时间复杂度 O(100n2)

Day2B

简要题意:给出 n500 个字符出现的频率 ai109,构造一棵保序k60 进制哈夫曼树,使得每个字符的编码与频率的乘积之和最小,输出这个最小值。

解析:设 fl,r,k 表示区间 [l,r] 划分为 k 棵子树的最优策略,gl,r 表示区间 [l,r] 的最优策略。

每划分一次,层数就会增加,所以加上 i=lrai,可以用前缀和 q 维护。为了方便实现,这一部分可以在最后统计 g 的时候再加。

fl,r,i=minmid=lr1{fl,mid,i1+gmid+1,r}gl,r=mini=2k{fl,r,i}+qrql1fl,r,1=gl,r

答案是 g1,n

时间复杂度 O(n3k),数据太水可过。

Day2C

简要题意:一个 n×mn,m200)只含 .# 的矩阵,进行以下流程求它的分数:若这个矩阵只有一种字符,分数为0。否则,则考虑所有的沿水平或者竖直方向的直线,将矩阵分成两个不为空的子矩阵,设两个子矩阵的分数分别为 ab,则原矩阵的分数为所有划分方法中 max(a,b)+1 的最小值。

解析:直接枚举矩阵的上下左右界肯定爆炸,但是发现每一个矩阵最终的分数都很小,不会超过 log(n)+log(m),并且对于上下左边界相同的矩阵,分数随着右边界的增大而增大。

因此,设 f(u,d,l,ans) 表示矩阵左上角为 (u,l),下界为 d,分数为 ans 时,右界的最大值。

同时,对 # 求一个二维前缀和统计个数。

先预处理出 f(u,d,l,0) 的情况。

横着分割:

f(u,d,l,ans)=maxi=ud1{min(f(u,i,l,ans1),f(i+1,d,l,ans1))}

竖着分割:

f(u,d,l,ans)=f(u,d,f(u,d,l,ans1)+1,ans1)

状态数 O(n3logn),转移 O(n),时间复杂度 O(n4logn),优化:

对于上,左,右界相同的矩阵,最优分割点随着下界的增大而增大,所以单调性优化,不再从 u 开始枚举 d,转移的 O(n) 就没了。

此外 ans 一维可以滚动数组。

答案是当出现 f(1,n,1,ans)=m 时,ans 的最小值。

时间复杂度 O(n3logn)

Day2D

简要题意:有 n 个物品,每个物品位于位置 aim 个黑洞,每个黑洞位于位置 bi。每次操作让所有物品向左(位置 1)或向右(+1),物品碰到黑洞就会消失(黑洞不会消失),直到所有物品消失。设第 i 个物品因为编号为 pi 的黑洞而消失,求不同的 p 序列的个数。(n,m105ai,bi109

解析:设 li 表示物品 i 去到左边的黑洞有多远,ri 表示物品 i 去到右边的黑洞有多远,A 表示所有物品向左移动过的最远距离,B 表示向右移动过最远的距离。

liA,物品被左边的黑洞吸走,riB,物品被右边的黑洞吸走。

(li,ri) 映射到平面直角坐标系上,每次操作都会让 AA+1BB+1,因此每次操作后 (A,B) 组成的折线是一根向右上角走的折线。liA 即为位于折线左侧,riB 即为位于折线右侧。

因此,问题变成求有多少条向右上方走的折线划分 (li,ri) 组成的点集。

可以用二位偏序,设 fi 表示以 (li,ri) 为折线的右上角,折线的方案数。

fi=li>ljri>rjfj

需要离散化优化。

时间复杂度 O(nlogn)

Day2E CF372C Watching Fireworks is Fun

解析:先把 bi 全部加起来,减去 |aix| 的最小值即可。

fi,j 表示第 i 场活动人在 j 的“|aix|”的最小值。

f1,j=|a1j|fi,j=mink[1,n]|jk|Δt{fk}+|aij|

单调队列和滚动数组优化。

答案是 bimin{fm,i}

时间复杂度 O(nm)

Day3A CF220B Little Elephant and Array

解析:莫队板,卡常能过。

时间复杂度 O(nn)

Day3C CF575I Robots protection

解析:先把四个方向的分开处理,后面都旋转成方向一的形状。

对于一个三角形,限制的是:

x[x,n]y[y,n]x+y[x+y,x+y+len]

画个图会发现,满足 y[y,n]x+y[x+y,x+y+len] 的部分减去满足 x[1,x1]x+y[x+y,x+y+len] 就是要求的部分,开两个二维树状数组分别维护即可。

Day3D P6847 [CEOI2019] Magic Tree / CF1193B Magic Tree

解析:设 fu,i 表示以 u 为根的子树,其操作全部在时间 i 及以前完成。

  1. 不获得 u 的果汁:fu,i=fv,i

  2. 获得 u 的果汁:fu,i=wu+idufv,du

两者取 max 得到 fu,i,时间复杂度 O(nk),线段树合并优化。

Day4A

简要题意:一个长度为 n5×104 的只含 az 的字符串,进行 q5×104 次操作,每次操作将 [l,r] 升序或降序排序,求最终的序列:

解析:开 26 个线段树维护 az 连续段的左右位置,每次排序可以很快的求出这一段里每个字母有多少个,然后根据排序就可以算出每个连续段对应的左边界和右边界。

但是暴力做法也能卡过,可以运用计数排序(即将每个数放到数轴上在顺次取,适合值域小的情况)卡到 O(nq),然后三秒时限直接玄学优化。

Day4B

简要题意:有 n 个数 ai,有 m 次操作,操作一单点修改 a 数组,操作二求随机选一段长度为 k 的连续区间,不同数字的个数的期望值。n,m,ai105

解析:计算出所有长度为 k 的区间的种类个数后除以长度为 k 的子区间的个数即可。

对于每个数字单独考虑。当选中的区间位于两个数字中间的空白段时,则这段区间无法被这个数字贡献(不同数字的个数),若两个 1 中间长度为 3,则有 3 个长度为 1 的区间,2 个长度为 2 的区间,1 个长度为 3 的区间无法被数字 1 贡献。

所以考虑维护每种数字中间的空白段,若从 x 改成 y,就是 x 左右的空白段合并,y 分裂 y 所处的空白段。

观察 若两个 1 中间长度为 3,则有 $3$ 个长度为 $1$ 的区间,$2$ 个长度为 $2$ 的区间,$1$ 个长度为 $3$ 的区间,发现区间的长度和不能被贡献的区间的个数,可以表示为一次函数 y=x+m,树状数组维护即可。

Day4C

简要题意:有一个有无限个房间的酒店,从 0 开始编号,一开始里面住满了 0 号队伍。

如果新进来一个有 k 个人的队伍,则先前房间 i 里的人移动到 i+k,新队伍住进 [0,k1];如果新进来一个有无限个人的队伍,则先前房间 i 里的人移动到 2i,新来的所有人住进每个 2i+1

询问 q3×105 次队伍 k 编号最小的房间,或编号为 k 的房间里住的几号队伍。

解析:观察到对于 i 号队,它们 x 个队员的房间分布一定满足 y=kix+bi,第一种询问直接用【模板】线段树 2 的方法就可以维护.

第二种询问,考虑哪个团队最终会选中这个房间,直接时光倒流:

  1. 新增一个房间,等待被一个队伍选取。

  2. 若出现一个有限人数为 k 的队伍,则编号 <k 的房间全部被这个队伍选取。

  3. 若出现一个无限人数的队伍,则编号为偶数的房间全部被这个队伍选取。

用一个 set 维护即可。

Day5A CF1795D Paint the Tree

解析:先让染红和染蓝走到两点的中点会合,然后以最短路径将整棵树遍历一遍即可。

Day6A

简要题意:给定一棵 n106 个点、带边权的树,计算以哪个点为根时,根到其他点的距离和最大。距离定义为两点之间路径上边权最小值。

解析:维护 max/min 问题很难直接维护,因此考虑时光倒流,每个点都变成孤立的点,依次加入边,这个操作可以用并查集维护。

然后考虑统计答案,设 maxxi 表示以 i 为根时,根到其他点的最大距离。

fxfy 进行并查集合并时(fxsiz 大于 fy),maxxfxmax(maxxfx+w×sizfy,maxxfy+w×sizfx)

Day6B

简要题意:有一棵 n3000 个节点的树,每个节点有一个权值。求相同权值的点数超过连通块点数一半的连通块的个数。

解析:分开每种权值考虑,将与当前考虑权值相同的点权设为 1,与当前考虑权值不相同的点权设为 1,若存在一个连通块权值和大于零,则说明这个连通块是一个满足题意的连通块。

fu,i 表示以 u 为根的子树中,连通块权值和等于 i 的方案数。

fu,i+j=fv,ifv,j

如果以 u 为根的节点颜色是 i 的有 ci 个,而存在 fu,j,其中 jci,这一部分的子树肯定是没用的,直接扔掉,时间复杂度优化到 O(nci)=O(n2)

Day6C CF1111E Tree

解析:考虑深度从浅往深放。

fi,j 表示考虑前 i 个节点已经划分成 j 组的方案数,节点 i 它的祖父有 ci 个。i 不能和它任何一个祖先划分为一组,所以有两种方案:

  • i 自己开一组:fi,jfi1,j1

  • i 和不是自己祖先的划为一组:fi,jfi1,j×(jci)

维护它的祖先的个数,用树链剖分即可。

Day6D

简要题意:两棵树共用若干个节点,A 可以在红树上移动,B 可以在蓝树上移动。输出 B 能捉到 A 的最少步数(双方都绝顶聪明),如果 B 捉不到 A,输出 1

解析:

  • 如果存在一条红边,它两端的端点在蓝树上的距离 3,那只要 A 到达这条边的两端,它就可以无限瞬移。

  • 如果某个节点,A 过去比 B 过去要慢,那 A 肯定不往那边走。

将下面那种点打上标记,如果不经过下面那种点能达到上面那种点,那么就输出 1,否则,走到能走到的在蓝树上深度最大的点。

这不纯纯 dfs 模拟题了。

Day7A CF437C The Child and Toy

解析:由于一个点删 x 条边就得付出 x 倍的代价,所以每条边的结果相互独立,互不影响,每条边直接删它两端较小的那边就可以了。

Day7B

简要题意:Alice 和 Bob 在一个有向图(点数,边数 105)上轮流移动棋子,Alice 先手,分数是经过的所有节点的最大值。Alice 想最大化得分,Bob 想最小化得分。从每个节点出发,Alice 的得分是多少?

解析:设状态 (i,A/B) 表示到达 i 号节点,且下一步是 Alice / Bob 移动。

根据得分的机制,经过 max 后的路径如何并不会影响答案,所以可以将 max 从大到小考虑,每一轮统计出所有可以到达 max 的状态。这样有效的解决了环的问题。

首先将那些已知的可以到达 >max 的状态全部丢进一个集合 S 里面(表示后面不可取)。

若从 (i,x) 能够到达 max,则说明有一种转移:(i,x)(j,¬x)(k,x)(max,A/B),这个序列应满足:

  • 所有状态均不处于集合 S 中,不然可以走到 >max 的数。

  • 对于每一个状态 (u,A)u 的任意一条出边的节点 v 的状态 (v,B) 必须不处于集合 S 中,否则 Alice 可以沿着 (v,B) 前往更大的节点。

  • 对于每一个状态 (u,B)u 的任意一条出边的节点 v 的状态 (v,A) 必须处于集合 S 中,否则 Bob 可以沿着 (v,A) 使其前往更小的节点。

所以代码的实现就可以沿着上面的思路:拿出不在 S 中的 (max,A/B) 作为起点,沿着它的反边行走,看一下它的前继状态是否满足上面三条要求,沿着这个状态继续向前找。写一个像拓扑排序一样的东西即可。

Day8A

简要题意:n 个点 m 条边的有向图,每个点权值是 az,一条路径的权值是该路径中点权出现最多次的权值,出现的次数。求最大路径权值。

解析:Kosaraju 缩点跑拓扑排序 DP 即可。

Day8B

简要题意:一个机器人在一个有向图(点数,边数 2×105)上走,走到自己走过的路径或者无路可走就自毁,遇到交叉路口可以花费 1 代价让它按指定路线行驶,否则它将随机移动。求每个点到达 t 的最小代价,无解输出 1

解析:考虑到可以从终点反推走到这个点所需要的代价。设 fi 表示节点 i 走到 t 的最小代价。用 u 表示每条边的起点,v 表示每条边的反点。随机走就按最坏情况走,显然有:

fu=min(maxuvfv,minuvfv+1)

ft=0,沿着正图反着走,采用 01BFS + 拓扑排序 的方法。

补充:01 BFS 是一种使用双端队列处理边权只有 01 的图的最短路的算法,时间复杂度为 O(m),其贪心思路为:不断取出队首的点处理,若遇到边权为 0 的边,这种边要多走,放到队头,否则放到队尾。可以证明双端队列中的元素从队首到队尾单调递增。

给每个点统计入度,当是 maxuvfv 的情况且入度为 0 时,放到队头;另一种情况需要立马转移,不管入度直接放到队尾。


后记:这样一看我也就补了一半都没有的题,菜!

最近更新