thuwc2020咕咕记+题解

前言

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

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

Day -?

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

Day 0

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

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

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

Day1

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

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

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

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

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

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

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

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

Day2

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

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

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

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

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

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

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

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

晚上回宾馆快乐颓废。

Day3

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

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

嗯。然后就跑路回广东了

Day 4

还是广东舒服呀!

题解


Day1T1

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

Day1T2

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

Day1T3

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

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

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

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

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

原题解

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

Day2T1

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

Day2T2

学考完了。学考无聊的时候想出来了。
一个 D A G DAG DAG去掉一棵外向树后剩下的应该是前向边和交错边。
考虑去掉这个外向树上一条链 a − > b a->b a>b后,如果这条链最底端的点 x x x能被到达,显然就是存在一个 d e p dep dep最小的点 u p x up_x upx满足从 u p x up_x upx走到 x x x不需要经过他们之间的边,且 d e p u p x ≤ d e p a dep_{up_x}\leq dep_a depupxdepa
对于子树内的点,要么他们的 d e p u p y ≤ d e p a dep_{up_y}\leq dep_a depupydepa,要么他们到 b b b中存在一个祖先 d e p u p a n c ≤ d e p a dep_{up_{anc}}\leq dep_a depupancdepa。这么看来,我们只需要求出这个 u p x up_x upx就可以算答案了
考虑求 u p x up_x upx,按拓扑序转移。如果一条边是前向边,那么当前点的 u p x up_x upx能对 u p p r e x up_{pre_x} upprex m i n min min,否则这条边是交错边。设出发点为 p r e x pre_x prex,求出 L C A ( p r e x , x ) LCA(pre_x,x) LCA(prex,x),那么从 L C A ( p r e x , x ) LCA(pre_x,x) LCA(prex,x) p r e x pre_x prex这段路径上的所有点的 p r e x pre_x prex均可以随便取。用 log ⁡ n \log n logn的数据结构随便维护一个向上的链最小值即可。这样的正确性可以通过考虑最后一条树边在哪里得出
求出了 u p x up_x upx后,按 b b b深度离线从大到小求答案。那么每次可以对一段 d e p u p y ≥ d e p u p n o w dep_{up_y}\ge dep_{up_{now}} depupydepupnow y y y来修改。线段树维护 d e p u p x = i dep_{up_x}=i depupx=i的点有多少个,那么每次先左右儿子线段树合并,然后相当于 c u t cut cut掉一条右链再在一个地方新增一条链, log ⁡ n \log n logn询问即可
总复杂度 n log ⁡ n + q log ⁡ n n\log n+q\log n nlogn+qlogn

Day2T3

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值