ICPC2023济南站题解(A B D E G I K M)
本场队伍整体实力较强,金牌线为低罚时7题。做出8题可稳金牌,这里是难度前8题的题解。
1|0ICPC 2023 济南站
1|1D:
本场签到。
1|2I:
可以区间排序,那么肯定是贪心地找最大的区间。
正解就是从左到右,遇到 的位置就找最右边第一个小于 的位置,将区间排序。
复杂度n方绰绰有余,正确性证明:每次至少能排好两个数的位置,即当前位置 i 和 i+1。可以满足题目 的要求。
1|3A:
感觉官方题解写的有点问题?说下我觉得更简单的思路。
首先题目保证了必定是合法的括号序列,如果不保证的话怎么判断是否合法:依旧是用一个栈,由于没有左右括号区分,我们用贪心的思想,如果栈顶与当前位置括号相同就出栈,否则入栈。如果是有唯一方案,那就是这种方案,方案不唯一的话说明有的位置可以不出栈。
为了表述方便,我们将形如 ([([])])
连续嵌套的括号序列称为 “小山峰”,注:必须是两种括号交替才算,比如 (())
认为是两个小山峰,因为可以变成 ()()
。
本题结论就是,所有合法的序列最多有两个独立的小山峰,一个最外层为方括号另一个为圆括号,如 ([]) [([()])]
。
证明:
首先两个相邻的小山峰最外层括号不能一致,否则翻转最中间的两个就会出现第二种情况,例:([()]) ([])
变成([()]( )[])
。
其次不能有三个小山峰左右排列在一起,由上面第一条知道,第一个和第三个小山峰最外层是一致的。翻转第一个小山峰最右边的括号和第三个小山峰最左边的括号,就会出现第二种情况,例:() [] ([])
变成(( [] )[])
。
然后是一个括号内不能包含多个小山峰或单个符号相同的小山峰:原因也很简单,如果括号内有多个小山峰,必定会有一个小山峰最外层可以翻转,例:单个符号相同( ([]) )
变成( )[]( )
,包含两个( [()] () )
变成( [()] )( )
。
综上,合法的所有情况就是最多两个小山峰,一左一右。这种情况的判断也很简单,就是满足 i 和 i+1 括号种类相同的位置最多有两个。
1|4G:
过的人没A多,但我觉得这种典题反而更容易想出来。
这种两两冲突的问题很容易转换成图论,一条边连两个点,两个点只能选一个。复杂点的题目可以用2-sat,这题是普通的二分图染色。
如果有两行的同一列都是1,那么这两行必须让某一行翻转,这就是一种冲突。后来发现不能单纯记录这一种冲突,因为有的关系是要么两行都翻转,要么两行都不翻转。
这种题也好解决,只需要把每行拆成两个点,一个表示“翻转此行”,另一个表示“不翻转此行”,两个点只能选一个,因此给他们连一条线。
对于两行同一列都是1,必须翻转某一行,那就把“翻转A”和“翻转B”连,“不翻A”和“不翻B”连,表示两个点只能翻转一个。
对于两行镜像列分别为1(第i列和第m+1-i列),两行状态必须保持一致,那就把“翻转A”和“不翻B”连,“不翻A”和“翻转B”连。
如果某列(加上镜像列)超过3个1,或者最中间的列超过2个1,不合法。无法对整个图进行二分图染色,也不合法。
方案数就是2的连通块个数次方,比较经典的计数。
1|5K:
先把 变成 。
将某一个区间全部变成同一个数的最优方案,就是所有数往中间凑,容易发现往中位数凑是最优的。
维护中位数的数据结构,可以用对顶堆(顾名思义,一听就懂),由于这题涉及到删除,可以用两个multiset。
由于此题的性质:如果大区间可以满足要求,那么小区间一定也满足要求,因此从左到右的每一个L,其最远位置R也是向右递增的。这就是做出此题的第二个关键点,用双指针。
R向右移动就是加入一个值,L向右移动就是删除一个值,用两个multiset一个记录较小一半,一个记录较大一半,使所有数相同的总步数为较大一半的和减去较小一半的和。复杂度O(nlogn)。
维护二顶堆时为了防止越界,可以先往左堆压入一个负无穷,右堆压入一个正无穷,由于中位数游离在两堆之外,因此需要按照总个数的奇偶分类讨论。
1|6M:
银牌计算几何题。
有两种做法,都需要极角排序。这里提供一个以O为极点,从向量OP开始逆时针排序的板子(注:只排角度不排长度):
此题第一种解法是枚举凸包内部的点作为极点,排序后发现如果凸包上某一条边满足题意,需要这个小三角形内没有其他点,也就是凸包上这两个点极角排序顺序相邻。
第二种解法是枚举凸包上的边,看看内部哪些点和这条边组成的三角形中没有其他点。这是一个经典的二维偏序问题。先按第一个点排序,记录每个点的排名,保持这些排名不变再按第二个点排序。
满足题意的点特征很好推,这里不方便讲,自己画画就知道了。
第一种解法代码:
第二种解法代码(相同函数省去):
1|7E:
1e5的数据,n方的二分图匹配求法都求不出来,发现边数较少,所以只能是网络流了。
这题dinic的复杂度不太会证,估计这题很多队没过的原因也是因为超时,CF的评测机dinic是可以跑过的,所以就只讲个思路当做参考了。
考虑跑完二分图匹配后残余网络的意义:从源点出发已经无法找到一条增广路到底汇点,因为所有的路已经被割了。
我们只需加一条边,使得这张残余图产生一条增广路即可。
正解:DFS查找从源点出发可以到达多少点(而且是二分图左边的点),以及有多少点可以到达汇点(而且是二分图右边的点),乘起来就是答案,思路还是比较简单的,稍微知道残余网络长什么样就能想出来(虽然这题想出来不代表评测机跑得过)。
这份代码勉强跑得进3s:
1|8B:
树形背包,但是人尽皆知是n^2,怎么优化。
根号分类讨论:
对于k小于根号n的情况,直接树形背包跑,时空复杂度均为 O(nk):上限为k的树形背包复杂度证明
对于k大于根号n的情况,我们思考会发现合法的情况并不多,这棵树切割的次数也非常少,我们还是用同样的转移方程,但是空间上用unordered_map来代替第二维,只记录方案数不为0的情况。
这样的情况总共有多少种,我们设大小为siz的子树里切了i个大小为k的块,那么根据题意可以推出:剩余的块大小一定为 ,因此一个 i 对应一个剩余块儿状态,每棵子树最多有根号个状态,和 k 小于根号 n 时的理论复杂度是一样的。树为一条链时复杂度拉满。
但是由于第二种情况用了unordered_map,为了平衡复杂度,我让根号的取值更大一些,让第一种情况充分跑满时间和空间(我是把根号值设到了660)。稍微改一下就卡过去了。
第二种情况代码的细节需要再多说几句:
1:因为我们只需要记录答案不为0的状态,所以出现答案为0的访问我们要立即删除,否则会越滚越多(即使没有赋值,只访问也是会往map里加入键值对的)。
2:STL比较吃内存,记得用完垃圾及时回收,map.clear()即可。
2|0后记:充满遗憾的散伙场
和我组队的是两位学长,有一位即将毕业了,所以今年是我们队伍最后一年,明年需要重组。
UESTC_404,我们调侃自己是老银牌队,因为之前所有的比赛都是银牌,银牌首、中、尾都拿过。但这最后一场比赛,却是以铜牌告终。
赛季前,我们学校发生了闻名贴吧的 “电子科技大学22只雄性事件”,所以我们中文名选用了 “UESTC_三只雄性”。
热身赛做完四道题之后,我们发现我们队正好在菜狗上面,非常兴奋,赶紧拍照留念,虽然后面我们两队中间又夹了几个队,不过有幸拍到了那一刻。我们觉得是个好兆头。
正式赛的第一个小时我们顺利做完了 D G I 三道题,A题稍微卡了下也在半小时之后做出来了,殊不知这就是整场所有的戏份了。
之后我看了E题,随口提了句 “跑完网络流在残余网络上搞搞试试?”,但是发现基本没人做就放弃了,先看 K 和 M。
我和队友 K 题的思路有分歧,我是想先差分,然后题意转化为左右移动小石子使得区间全为0,队友觉得应该先二分,然后数据结构维护下。后来想到对顶堆可以维护中位数,我就上去写,我的脑子就是从这时候开始混沌的。
二分答案(序列长度),再套个STL,本来就是俩log,我一直觉得不放心。一开始我选的是priority_queue,因为涉及到删除,我用一个数组来表示每个数的剩余数量,发现很难写,调了很久样例都没过,浪费了好多时间,队友说换成set不就好写了,对啊,我就赶紧又写了份multiset。
这段时间是比较难熬的,因为两个log自己都觉得过不去,却还是硬着头皮写完了,(我们一直在想怎么优化掉STL的这个log来着),期间唯一欣慰点的是队友会做 M 了。
一交,果然TLE了,悬着的心终于死了。
赶紧换队友写M,这时候已经知道自己与金牌无缘了,想着这场能过六题就知足了。
队友改了很久的排序顺序(应该是二维偏序那里,“正着不对?换倒着试试”),终于过样例了,然后一交,WA。
然后我们队就死气沉沉了,我还一直在想 K 题怎么避免用STL。终于队友发现根本不用二分,用双指针就行了,匆匆忙改了改,交上去变成了RE,这下给整不会了。
我一直以为是我们的双指针越界的问题,因为数组开的够大,而且set里有无穷大,应该不会是STL越界的问题。直到前几天补题(揭伤疤的感觉),才知道multiset在erase时,如果是迭代器,则只会删除一个值,如果是数值,会把所有位置全删掉。我们这题就是因为删的数多了所以RE掉了。
也不能怪时运,其实是自己STL基础没打好,唉。
至于M题,其实到现在还不知道WA的原因。
我们队就一直被这两题卡着卡到比赛结束,最恶心的一场。
我们学校的另外两个队,WiFi和花火,都是8题金牌(WiFi其实也是崩了,只做了8题)。我们却只有4题,4题首位,甚至领先第二80分钟。
大一刚打ICPC时,我一直期望的是学长带飞自己,所以一直是漫不经心。这场打完之后,我突然觉得作为学弟更应该负起责任,因为明年,我还有机会参加比赛,但学长的成绩就只能止步于此了。
这场ICPC成为了我们几个人参赛以来最大的遗憾,因为要散伙了,难免会有些气愤,感到时运不济之类的(比如回来的飞机上我突然觉得E怎么这么简单,之前做过好几道处理残余网络的题)。
虽然今年与EC无缘,但是我才大二,明年还有机会。需要有把自己作为队伍主力的心态,即使不是主力,也要以此为目标去努力,以后才能至少不像这场散伙赛一样让人感到遗憾。
__EOF__

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)