CSP-S 2022 Unofficial 题解

Author: Plozia, written on 2022/10/30, finish on 2022/11/1。

T1 假期计划(holiday)

首先可以预处理每个点在走了 k+1 步之后能够到哪些点,n 遍 bfs 即可,这样我们就知道了每个点后面或者前面能跟哪些点(前面也可以是因为无向图)。

做法就是暴力 bfs,队列里面存一下这一路过来哪些点走过了,然后可以过 O(n4) 能过的点以及 k0 的点,然后看起来就没有什么算法可以优化了。

但实际上有个叫 meet in middle 的相对冷门的玩意,这玩意就是处理前半段处理后半段然后拼接,考虑到这题上,因为题中要求 4 个不同景点 A,B,C,D,考虑枚举 B,C,此时问题就变成了 1AB,CD1 然后拼接,对所有点 x 预处理 py,满足 xy,y1 成立并且 ax+ay 为前 p 大,这样可以枚举 B,C 然后暴力合并前 p 大即可,可以证明 p 最小值为 3,然后就过了。

注意点就是 BC 需要成立,然后 A,B,C,D 不重合。

好像有人在预处理的时候先跑了 n 遍 bfs 求两两之间最短路,但是这个做法要判连通性不然会寄,直接存下能到哪些点不是更舒服吗,连通性也不用判(

T2 策略游戏(game)

这玩意赛时我按照两个人区间内只有正数,只有负数,正负都有大力分类讨论九种情况,然后接上含有 0 的情况大概分讨了 18 种,虽然烦但是保证对,毕竟合并情况之后谁还知道对不对呢(

update:上面做法少了几种情况,还需要讨论区间里面只有 0 的情况,直接输出 0 即可但是可以卡掉(

大众写法是只考虑第一个人的正负情况,第一个人选正的后面这人必选最小值,第一个人选负的后面这人必选最大值,第一个人选 0 后面这人咋选也没用,实际情况中可以将 0 归到正数的情况。

因此考虑求出第一个人正数的区间最大最小值,负数的区间最大最小值,第二个人的区间最值,然后就只有 4 种情况了(第一个人选正最大正最小负最大负最小),取个最大值即可。

T3 星战(galaxy)

题意简化:给出 nm 边有向图,初始所有边存在,有四种操作,1,3 操作是删除一条存在的边或者是恢复一条被删除的边,2,4 操作是将一个点的所有入边全部删除或者是将一个点所有入边恢复,问每次操作后所有点的出度是否为 1(实际上题中还有一个条件是所有点自选路径往前走可以走无穷步,但是出度均为 1 是这玩意的充分条件)。

为什么 CSP-S2021 T3,NOIP2021 T3,CSP-S2022 T3 全是人类智慧啊(

首先 1,3 操作是能够 O(1) 的关键是 2,4 怎么办如果暴力模拟实现的好可以做到 60pts,但是如何做到可接受复杂度。

然后就有一种 hash 乱搞的做法,可以维护和也可以维护异或,两者本质差不多,这里讲讲第二种做法。

考虑对每一个点随机一个权值 ai(最好是用 mt19937_64 开到 unsigned long long 范围内),这样每个点出度为 1 就变成了如下两个要求:一是总边数为 n,二是所有边的起点权值异或和为 i=1nai

这样 2,4 操作就好维护了,因为题中保证删边加边操作合法,所以我们只需要知道一个点的所有入边的起点异或和即可,然后因为异或有结合律所以可以做到 O(1),至于维护边数显然可以 O(1)

T4 数据传输(transmit)

首先 k=1 的情况显然就是个树上路径点权和。

k=2 的情况时取出 st 这一条链,然后注意到不会跳到链外的点(因为边长限制为 2,跳出去显然会使答案变劣),因此可以设计一个 dp ,fi 表示到第 i 个点的最小答案,有 fi=min{fi1,fi2}+ai

k=3 的情况有点不一样了,因为可以跳到链外面的点,如下图:

image

此时一个状态不够了,需要两个状态 fi,j,这题第二维维护离 i 的距离,也就是说 fi,j 表示当前处在距离点 ij 的点上的最小值。

使用这个状态之后,考虑一次从点 xy,fax=y 的转移,不难写出如下转移方程(ay 表示距离点 y 为 1 的所有点的 ax 最小值):

fy,0=fx,0+ay(k=1)

fy,0=min{fx,0+fx,1}+ay,fy,1=fx,0(k=2)

fy,0=min{fx,0,fx,1,fx,2}+ay,fy,1=min{fx,0,fx,1+ay},fy,2=fx,1(k=3)

注意到上述转移方程对于 fy,1fy,2 的处理似乎有点不对,因为可能会有 fx,1 跳三步到 fy,1 但是点不一样的情况,或者是 fx,0 跳两步到 fy,0 但是点不一样的情况,但是这样一定不优,因为上面说了状态和当前具体在哪个点没关系,这样跳只会使答案变大。

然后你注意到上式其实是个矩阵形式,重定义矩阵乘法 Ci,j=min{Ai,k+Bk,j},发现有结合律,于是就可以将转移方程写成下面这个样子:

[fx,0,fx,1,fx,2]×[ay,0]=[fy,0,fy,1,fy,2](k=1)

[fx,0,fx,1,fx,2]×[ay,00ay,0]=[fy,0,fy,1,fy,2](k=2)

[fx,0,fx,1,fx,2]×[ay,00ay,0ay,00ay,0]=[fy,0,fy,1,fy,2](k=3)

由于题目 k 值固定,所以每个点的转移矩阵也是固定的,这个可以预处理出来,然后将 st 按照 LCA l 裂成 sl,lt 两部分,按照自底向上和自顶向下维护即可,由于矩阵有结合律所以可以倍增。

具体的,设 fax,ix2i 级祖先,然后设 Upx,i,Downx,i 分别表示 [x,fax,i) 这条链上的矩阵乘积,其中 Up 为自底向上,Down 为自顶向下,这块可以倍增维护。

特别的,点 s 的初始矩阵为 [as],最后答案为所得矩阵的第一行第一列。

至于查询,考虑处理出点 s 的初始矩阵后将 fas,0l,fat,0l 倍增求出来然后三者相乘,最后乘上点 t 的转移矩阵。

这里不支持直接求 fas,0l,tl 的一个原因是倍增数组维护的是左开右闭区间,所以当 l=t 的时候无法将 t 的转移矩阵统计进去,所以为了统一方便就这么干了。

特别注意一下如果 ls,lt 则还需要在中间乘上点 l 的转移矩阵。

写代码的时候注意一定要让根节点父亲为 0,否则会出各种各样奇怪的 bug,然后注意重定义矩阵乘法的单位矩阵是 I=[000]

总结

注意到这场 T1,T2 还是比较简单的(显然 T1>T2),然后 T3 人类智慧题不做评价(虽然几年前就有这样的套路了)毕竟这玩意想到了代码 5min 的事情想不到就是 60pts 暴力走人,T4 是一个矩阵优化 dp 的套路题(要是带修就变成 ddp 了,还需要上树剖维护),所以这场总体还是简单但是我分数还是不高

update:T3 “不可以,总司令”有 45pts,然后如果两个结合起来分数更高,加上暴力卡时常数小点甚至能过 /jy

posted @   Plozia  阅读(362)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示