Codeforces Round #616 部分题解
Posted p-b-p-b
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #616 部分题解相关的知识,希望对你有一定的参考价值。
老年选手诈尸?
A,B
咕了。
C - Prefix Enlightenment
很容易看出这个限制条件可以推出每个点最多被两个集合包含。按照套路,很容易联想到给这两个集合连一条边,表示他们的状态要相同/不同。
因为保证了有解,所以从左往右扫的时候拿并查集维护一下每个连通块的二分图情况,选较小的那一边。
如果只被一个集合覆盖,那么就相当于强制这个集合选/不选,在做并查集的时候特判一下即可。
代码咕了。
D - Coffee Varieties (hard version)
作为一名憨憨,做法当然要与正解不同。(当然常数也比正解差……)
容易想到每种咖啡在最左边的位置统计。考虑暴力,枚举两个位置(i<j),加入(i),加入(j),清空。这样可以过(K=1)的情况。
考虑每(K)个点(注意不是和题解一样(frac K 2))分一个块。如果我们加入(A)块之后再加(B)块,那么(B)块中的每个点都与(B)块中的前缀和(A)块中的后缀做了比较。如果我们倒着加入(A)块之后再倒着加(B)块,那么(B)块中的每个点都与(B)块中的后缀和(A)块中的前缀做了比较。可以发现,此时(B)块中的每个点都和(A)块的每个点做了比较。
先不考虑(B)块中点会和比自己靠后的点作比较的问题,那么只要对于任意两个块都这么做一遍就行了。然而常数不太行。
我们先做正着加的情况。考虑做完两个块之后不清空,利用原有的信息。建一张图,(i)块向(j)块连边((i<j)),走这一条边相当于在队列中是(i)块时加入(j)块。那么我们需要每条边都走一遍。考虑给这个图加一些额外边,使得它存在欧拉回路,这样就可以一次走完。注意到第(i)个块和第(frac n K -i+1)个块的出度入度相匹配,可以额外连((frac n K -i+1,i,frac n K -2*i+1))的边,于是每个点的入度出度都相等了,可以跑欧拉回路。此时用的询问次数是(Km)的,(m)大概是(frac {3n^2}{4K^2})。
我们希望反着加的情况可以用类似的方法解决,但是反着加的时候(B)块中的每个点都与(B)块中的后缀做了比较,这不是我们想要的。
注意到正着加的时候我们已经把一些点给毙掉了,剩下的点在同一块中是互不相同的,于是可以倒着加的时候不加入被毙掉的点,而是加一些同块中还活着的点充数。
于是就做完了,询问次数几乎顶着上界,但是不需要清空队列。
我才不告诉你我没看懂正解呢
代码:https://codeforces.com/contest/1290/submission/73847748
E - Cartesian Tree
做这题的前置知识:定义(maxr(l))表示最大的(r),使得([l,r])是笛卡尔树中的一个区间,不存在则是(null)。(minl(r))类似。那么对于笛卡尔树中的一个区间([l,r]),只要不是根,那么(maxr(l)=r)和(minl(r)=l)就恰好会满足一个。
回到这题,考虑把插入换成往已经确定的位置里填数,也就是允许序列中有空位。
那么([l,r])的子树大小就是([l,r])中的非空位置个数,也就是(fp(r)-fp(l-1))。
考虑把这个东西用前置知识拆开,那么答案就是(sumlimits_{maxr(l) eq null} fp(maxr(l))-sumlimits_{maxr(l) eq null} fp(l-1)+sumlimits_{minl(r) eq null} fp(r)-sumlimits_{minl(r) eq null} fp(minl(r)-1)),再减掉一些关于根的常数。
据说前后是对称的,那么我们只考虑前面两项。
发现(maxr(l) eq null)等价于(p_{l-1}>p_l),于是第二项很好做。
对于第一项,考虑如何加入一个最大值后维护(maxr(l))。由于(maxr(l))就是((l,n+1])中第一个比(p_{l-1})大的位置减一,所以加入最大值就只会给前缀取min,以及单点修改自己和后继的(maxr)。
你发现这东西可以segment tree beats维护,而套上个(fp)其实也差不多,在外面额外用树状数组维护一下(fp)就好了。
大概是这样吧,代码暂时咕了,下午补。
F
咕了。
以上是关于Codeforces Round #616 部分题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #616 (Div. 2)
Codeforces Round #616 (Div. 2)解题报告
Codeforces Round #616 (Div. 2)
Codeforces Round #616 (Div. 2)