thuwc2020咕咕记+题解

本文记录了作者参加计算机竞赛的全过程,包括旅途趣事、比赛感受及详细题解。涉及算法如动态规划、图论、数据结构等,分享了解题思路与技巧。

前言

upd:更新了口胡题解
upd2: 全部fixed了…

不知道起啥名字。那就咕咕咕吧
这次看起来能写长一点…
看我心情

Day -?

隔壁的初审出了
thu的初审也出了
发现thu今年的分数线怎么比pku低这么多
人多警告
于是和艹哥还有远哥过了thu的初审

Day 0

坐飞机
似乎看了个很爽的电影。下飞机穿着广东穿的单薄卫衣差点没把我吹死
这温差也太大了吧,风怎么也这么大啊。
脸都要被吹没了
人没了人没了

然后教练以打车太贵的名义带我们坐地铁,站了快两个小时后终于苟到了酒店,结果人均跟打车看起来五五开…血亏。
到了之后发现房间居然还没打扫好,于是在大堂咕咕咕了一小时…
晚上去吃烤肉,在消费巨高的帝都成功苟命。然后回房战斗
听说pku今天没有试机qaq

11点睡了,感觉十分干燥
室内室外的温差是真的大啊。

Day1

出去吃沙县。
蒸饺好吃,还想继续吃。

吃完就出发去thu了,路上手差点要被吹成手雕。到了门口一看果然被家长堵的水泄不通…比较奇怪的是这次不在那个地下室考,换了一个更高明更多机房的地方考。报道还发了个围巾,巨型好评比隔壁不知道高明到哪去了
试机题是thuwc2018的题,调gedit的配置调了一年,还直接把一台电脑给试没了。于是随便把第一题写了就没时间跑路了。反正听说后面两个题不能搞的。
中午去蹭羊老师的饭。比我们学校不知道高明到哪去了。16块就有一大盘意面/se 随便聊了点东西就跑路了

下午开考,题面不记得了。似乎可以在ouuanouuanouuan的博客上找到)
花了5min写好gedit的配置,有一键编译和运行简直就是爽的飞天。

看题。第一题什么鬼,这kkk一定很小,往下一拉k≤20k\leq 20k20
上面居然还有k=1k=1k=1的分,这难道不是明示把每个人拆开看然后转移取minminmin?从后往前维护kkk个单调栈上二分就可以了吧…knlog⁡nkn\log nknlogn,随便一写10min写完就过了。交上去居然还可以看final test的结果的。奇妙无比

这第二题什么鬼,明示我动态维护这个基环树?这是不是可以写个lctlctlct把根丢在环上来搞啊,看起来很对啊。于是当机立断立刻开写,写了1h发现情况实在太多不是人写的,觉得能切掉的人应该也不多,于是开始糊暴力
写了一发暴力,发现居然过了一车task。这pt莫不是拿脚造的…
开始写w=1e18w=1e18w=1e18,随便写了个倍增就过去了。
开始写树,随便剖了一下再套一个线段树二分就过去了。
于是pt=57pt=57pt=57,看起来下面有个task应该不能过。于是应该final=49final=49final=49

这第三题什么鬼,不会啊。
想了个假结论,乱fix了几发,还好都被我手造的数据给卡了… 于是开始堆暴力。
写个暴力只有444分的好成绩,写个X=299999X=299999X=299999又有444分的好成绩。发现X=299900X=299900X=299900最多只有100100100个点的区间,然后思考了一下发现这个东西如果要强行卡的话很难卡住,加个记忆化后似乎就可以暴力踩过去了,然后又获得了161616分的好成绩。然后开始乱搞性质点,发现一条链貌似极其可做,可以大力转化成一个森林,连通块个数就是没有向前连边的点的个数。直接拿个setsetset预处理一下[l,r][l,r][l,r]表示询问在其中的时候这个点不会向前连边,询问就直接是个二维数点了。然后又获得了161616分的好成绩,然后比赛就结束了…

今天出来貌似是pt=100+57+40=197pt=100+57+40=197pt=100+57+40=197…感觉极其大众还没算fst的

晚上去吃火锅。然后学长们一直在聊聊聊,我就一直在吃吃吃。除了吃的晚了点没法回去颓外都挺不错的。
大概11点又睡了

Day2

不想早起,于是在房间里解决早餐。然而貌似预估时间错误,走是不可能及时到的了,于是直接骑了个车莽进thu。顺便get了剩下几天的代步工具。成功在开始前5min抵达考场。大力敲完gedit配置
一键编译和一键运行是真的香啊

开考,发现这个第一题我不会做。猜了个结论跑,结果直接莽过了task2,3,4task2,3,4task2,3,4,剩一个task1task1task1不会。然后想了想貌似可以手造一个卡掉,但是似乎大一点的我就很难弄出来了。出题人都是懒的直接拼起来,假装能过。挂了个拍试图找个挂的数据,结果最后都没拍出来…

发现这个第二题我也不会做。似乎DAGDAGDAG题我都不会做。然后一直在上厕所游荡,发现很多鸽鸽敲起来了线段树/splay合并。莫不是在写那个5min被我叉掉的做法qaq…? 试图刚出来正解然而并没有什么用,浪费了无数时间最终选择写暴力后滚去了第三题…
隔壁的两位鸽鸽都调这个合并调到了结束…为他们默哀…

这个第三题看起来十分可做,在草稿纸上推了推感觉肯定只与前缀最大值相关。然而当时头脑混乱并没有直接推出来式子是什么,于是先写了一个阶乘的不记得多少分暴力。然后又回去刚第二题
发现还有40min40min40min的时候选择放弃第二题,回来打了个表。发现确实只与前缀最大值的个数相关,只需要知道就可以O(log⁡n)O(\log n)O(logn)来算了。貌似结论是啥(i+1)!×(K+1)i(i+1)!\times (K+1)^i(i+1)!×(K+1)i这种形式的…忘了。
还需要判断可行性,似乎是最后必须要是前KKK大就是充要了
发现还有20min20min20min,迅速rushrushrush了一个询问一直是[1,n][1,n][1,n]的sub,获得了不记得多少分的分数。然后比赛就结束了…出门的时候想了想感觉会了log⁡2\log ^2log2做法…感觉十分败笔,不来刚t2t2t2选择刚t3t3t3这把我就赢了。
pt=100+20+27=147pt=100+20+27=147pt=100+20+27=147,第一题极有可能fst掉…

然而两天考场都有一个鸽鸽开场就狂敲然后提前离场,感觉实属恐怖无比。

回去啃了汉堡就睡了。
五点起来去吃了个面,吃完发现可能又赶不上了。于是再次骑车莽进thu

这次造cache总比造路由器好多了qaq
开始的时候居然还没有下发《学习手册》,感觉很憨。

第一题不知道是在干什么,看了大半本手册都不知道问题在哪。终于在倒数第二页发现了一个奇怪的表格。根据表格写了半天大模拟终于一遍过了ptptpt
第二题不知道是在干什么,似乎又是个大模拟
然后写了一个发现第一个task都过不去…点开.in似乎这个东西不是整数而是二进制数?,改成二进制仍然过不去。答疑了nnn次得到了无数个no response\text{no response}no response…最后一气之下改成了字符串哈希,终于过了
然后后面基本都是看懂就会。一路写下去,顺便发现那个问题原来在于…这个东西原来是个101010进制数
写完就剩下10min10min10min了,把第三题题面看了看就结束了。感觉打了个大众分低下的分数…pt=40+56+96pt=40+56+96pt=40+56+96

晚上回宾馆快乐颓废。

Day3

早上被一个电话吵醒,发现教练五点给我发面试通知,然后好像昨晚111111点半我就进面试了…
于是去面试,家长又是一车。
在座位上写自我介绍,抄了抄lh大爷的…今年居然给用手机,之前sc的时候是不给的qaq…
去面试的时候遇见了个奇妙老哥,出门大喊自己凉了,然后得到了yyl的diss
自我介绍被打断:“讲重点”
给了我篇居然能看懂的英文…大概是讲图论的一些基本定义。然后念完之后面试官用英文向我发问…我的poor english仅限于能听懂而不能表达自我啊qaq…随便糊了个dij用于导航之类的就尴尬了。
还剩半分钟似乎就问了我个奇怪问题。大概是一个人永远真,一个人永远假,两个人认识对方。你问一个问题来区分这两个人
发现我不会,于是尴尬了半分钟后被面试官挥手赶走了…
回房问艹哥,发现原来是智慧题。
面试估计垫底了。

下午去讲座,本来以为有讲题,结果发现一直在讲去年讲过的吹水课件…
吹水就吹水吧,这个厅这么小怎么家长还这么热情堆在后面…于是被迫坐在了门口玩手机
面基了lhf,一同狂喷奇怪制度以及题目。感觉gd老哥还是热情人好/cy
咕咕咕到四点半,发现招办的人来了。于是跟着招办挤过了人群
发奖不按顺序发,按学校发…于是也无从得知人数
最终还是苟到了个一等奖吧…上一个赛季的遗憾也算是完满了

嗯。然后就跑路回广东了

Day 4

还是广东舒服呀!

题解


Day1T1

多个人的情况与一个人没有差别,下一个转移的状态只需要分别对每个取min即可。从后往前维护k个单调栈上面二分即可得到答案。复杂度Knlog⁡nKn\log nKnlogn

Day1T2

裸的LCT维护基环树 谁爱写去写去吧。

Day1T3

upd 2020/07/27:更新一个简单的做法
当时做这个题的时候构造方法过于麻烦。我们再推一遍

由于点之间有边的充要条件是树上距离≤x\leq xx,我们尝试对每个树上连通块找一个关键点出来代表这个关键点。然后根据≤x\leq xx的这个性质,我们尝试用BFS序来给其维护

因为BFS序存在一个性质:满足若在BFS序条件下i<j<ki<j<ki<j<k,且(i,k),(j,k)(i,k),(j,k)(i,k),(j,k)之间的距离均≤x\leq xx时,(i,j)(i,j)(i,j)之间的距离也≤x\leq xx。我们考虑将点zzz的父亲定为BFS序比自身小的的满足dis(z,i)≤xdis(z,i)\leq xdis(z,i)x的点iii(多个可以任选一个)。我们考虑证明,每个非连通块内BFS序最小的点,其一定存在一个父亲

我们运用反证法:令与zzz同一个连通块的BFS序最小点为xxx,我们找到任意一条xxxzzz的路径x→a1→a2→⋯→ak→zx\rightarrow a_1\rightarrow a_2\rightarrow\cdots\rightarrow a_k\rightarrow zxa1a2akz。找到其中任意一个BFS序满足ai>ai−1,ai>ai+1a_i>a_{i-1},a_{i}>a_{i+1}ai>ai1,ai>ai+1的点,由上述结论,可知dis(ai−1,ai+1)≤xdis(a_{i-1},a_{i+1})\leq xdis(ai1,ai+1)x,故可以直接将aia_iai删除。我们发现删到最后,一定满足这个序列的BFS序是单调递增的。因此zzz一定存在至少一个直接与其连接的比其BFS序小的点。

那么我们只需要求出在原编号给定区间[l,r][l,r][l,r]中的xxx,存在多少个点满足没有父亲。我们可以处理出在两侧分别离xxx最近的,满足BFS序比xxx小的点是什么,记为(u,v)(u,v)(u,v)。那么xxx不含父亲当且仅当u<l≤x≤r<vu<l\leq x\leq r<vu<lxr<v。可以优化一波做一个简单的二维数点即可

原题解

其实跟我场上做法十分相似,应该类似csp的时候一样…推广一下就到正解了…但是当时混乱的一匹完全没大力推广呀…
图的连通块数一看就不好做,而森林的连通块数极其好做。就是没有往父亲连边的点的数量。并且通过链的部分分我们不难得到这个东西肯定与正解相关…
考虑将图转化为树,容易想到如果能将其转化为最小生成树就十分win了…开场的时候糊了几个结论直接用代表点构树发现都lose了…所以应该仍然观察这个图的性质。
将标号在[L,R][L,R][L,R]内的导出子图拿出来,建出他们的虚树。如果这个虚树没有新增点,那么每个点直接向虚树的父亲连边就一定是最小生成树了…否则考虑依次去掉点,每次去掉点一定至少有下方的两个点选择连向了他,否则直接将唯一的那个点继续往上连即可…我们可以简单地让下方每个点都选一个距离他最小的点连边,但是这样可能出现了重边/环/不会向上连边的情况。考虑钦定一个连边顺序使得不会出现环,将下方所有点按depdepdep排序,每个点强行只往depy<depxdep_y< dep_xdepy<depx或者depy=depxdep_y=dep_xdepy=depxy<xy<xy<xyyy连边。考虑这样是否正确,显然至少有一个点会往上连边(如果上面仍然存在点),并且类似拓扑序,一定不会出现环。所以这样连出来仍然是一棵树。考虑正确性,将这些点抽出来的话显然类似一个扫把,这棵扫把的MSTMSTMST显然是可以这么直接做的…分是会向上还是往左右兄弟连边讨论可证
以下称基本条件为depy<depxdep_y<dep_xdepy<depx或者depy=depxdep_y=dep_xdepy=depxy<xy<xy<x
所以现在只需要对于每个xxx,类似链的做法,求出最大的l<x,dist(l,x)≤Kl<x,dist(l,x)\leq Kl<x,dist(l,x)K且满足基本条件的lll,同样也求出最小的r>x,dist(r,x)≤Kr>x,dist(r,x)\leq Kr>x,dist(r,x)K且满足基本条件的rrr,那么剩下来就是只有[L,R]∈[l+1,r−1][L,R]\in [l+1,r-1][L,R][l+1,r1]的时候会对这个询问产生111的贡献…是个二维数点简单问题
唯一的问题在于如何处理这个l,rl,rl,r,以lll为例,将点分树建出来,按depdepdep从小到大排序加入。每个点在当前depdepdep全部加完之后询问,注意如果求rrr是加完之前询问。一个点往上暴力跳点分树考虑对当前分治中心的贡献,如果加入的点在分治中心在原树的子树内,那么可以直接用可持久化线段树加入,因为此时到分治中心的距离是单调不减的…否则在子树外,在子树外似乎是无法直接可持久化线段树暴力维护的…因为到分治中心的距离没有了单调性,但是考虑什么时候需要子树外的信息,显然就是询问点在分治中心的子树内。由于他到分治中心的距离是固定的,所以可以用一个类似c+depaskc+dep_{ask}c+depask的形式来搞。这样只对depdepdep在连续一段且在子树内的询问点有贡献,额外用一个简单的线段树来维护即可…
总复杂度nlog⁡2n+qlog⁡nn\log ^2 n+q\log nnlog2n+qlogn

Day2T1

每个函数的贡献都是kx+bkx+bkx+b的形式,其中kkk能让xxx绝对值不减,同时绝对值最多只会变化151515。所以维护[−225,+225][-225,+225][225,+225]内的可达性外加≤−225\leq -225225max,minmax,minmax,min≥225\geq 225225max,minmax,minmax,min是什么,O(1)O(1)O(1)转移即可

Day2T2

学考完了。学考无聊的时候想出来了。
一个DAGDAGDAG去掉一棵外向树后剩下的应该是前向边和交错边。
考虑去掉这个外向树上一条链a−>ba->ba>b后,如果这条链最底端的点xxx能被到达,显然就是存在一个depdepdep最小的点upxup_xupx满足从upxup_xupx走到xxx不需要经过他们之间的边,且depupx≤depadep_{up_x}\leq dep_adepupxdepa
对于子树内的点,要么他们的depupy≤depadep_{up_y}\leq dep_adepupydepa,要么他们到bbb中存在一个祖先depupanc≤depadep_{up_{anc}}\leq dep_adepupancdepa。这么看来,我们只需要求出这个upxup_xupx就可以算答案了
考虑求upxup_xupx,按拓扑序转移。如果一条边是前向边,那么当前点的upxup_xupx能对upprexup_{pre_x}upprexminminmin,否则这条边是交错边。设出发点为prexpre_xprex,求出LCA(prex,x)LCA(pre_x,x)LCA(prex,x),那么从LCA(prex,x)LCA(pre_x,x)LCA(prex,x)prexpre_xprex这段路径上的所有点的prexpre_xprex均可以随便取。用log⁡n\log nlogn的数据结构随便维护一个向上的链最小值即可。这样的正确性可以通过考虑最后一条树边在哪里得出
求出了upxup_xupx后,按bbb深度离线从大到小求答案。那么每次可以对一段depupy≥depupnowdep_{up_y}\ge dep_{up_{now}}depupydepupnowyyy来修改。线段树维护depupx=idep_{up_x}=idepupx=i的点有多少个,那么每次先左右儿子线段树合并,然后相当于cutcutcut掉一条右链再在一个地方新增一条链,log⁡n\log nlogn询问即可
总复杂度nlog⁡n+qlog⁡nn\log n+q\log nnlogn+qlogn

Day2T3

首先手绘一下,冒泡排序的方式只与前缀最大值相关,每次将前面移到后一个的前面。于是可以大胆猜结论,答案只与前缀最大值相关。
打表发现大概形式长一个(i+1)!×(K+1)i(i+1)!\times (K+1)^i(i+1)!×(K+1)i的样子。反正只要知道前缀最大值个数就能算。还需要最后KKK个是前KKK
于是可以有一个十分显然的nlog⁡2nn\log ^2nnlog2n的做法
考虑对树点分,将询问挂在他们点分树的LCALCALCA
利用点分治能求出当前分治中心到所有点的单调栈,可以在上面二分弹栈并利用小trick做到O(log⁡n)O(\log n)O(logn)弹出并O(nlog⁡2n)O(n\log ^2n)O(nlog2n)地维护所有点的可持久化单调栈
询问就直接合并就可以了
关于合法性,考虑维护最后一段极长上升连续序列。只需要这里面第KKK小比前面都大即可。利用点分同样不难在上界log⁡2n\log^2 nlog2n的时间内简单维护

补一个nlog⁡nn\log nnlogn的做法,上面的点分可以用奇怪的技巧优化到log⁡n\log nlogn
大家看徐国王的博客吧!

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值