前言
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
k≤20。
上面居然还有
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 x→a1→a2→⋯→ak→z。找到其中任意一个BFS序满足 a i > a i − 1 , a i > a i + 1 a_i>a_{i-1},a_{i}>a_{i+1} ai>ai−1,ai>ai+1的点,由上述结论,可知 d i s ( a i − 1 , a i + 1 ) ≤ x dis(a_{i-1},a_{i+1})\leq x dis(ai−1,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<l≤x≤r<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,r−1]的时候会对这个询问产生
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
depupx≤depa
对于子树内的点,要么他们的
d
e
p
u
p
y
≤
d
e
p
a
dep_{up_y}\leq dep_a
depupy≤depa,要么他们到
b
b
b中存在一个祖先
d
e
p
u
p
a
n
c
≤
d
e
p
a
dep_{up_{anc}}\leq dep_a
depupanc≤depa。这么看来,我们只需要求出这个
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}}
depupy≥depupnow的
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
大家看徐国王的博客吧!