Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F

Posted zhugezy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F相关的知识,希望对你有一定的参考价值。

C

对每一步结束之后往map里存个位置,看停留在相同位置的最少差多少步就行了。

D

(h\%(a+b)leq (x+1)a)(x_{min}=lceilfrac{h\%(a+b)}{a} ceil-1).然后贪心即可。

E1

注意到要把原字符串排序,每一对逆序对都要进行一次交换,即每一对逆序对的颜色都必须不同。因此所需的颜色数即为最长的逆序链长。

对E1,可以考虑建图,每个位置看成一个点,把每一对逆序对建边,很显然这就是判断是不是一张二分图。

E2

对E2,依次考虑字母a,b,c,...,z,给每个字母填上它当前能填上的最小数字。例如对样例abacbecfd,考虑到字母c了,当前字符串和涂色为

aba(c)b?(c)??
121(?)1?(?)??

对新加入的每个字母c,看在它后面的小于它的字母(a/b)的那些位置,填上大于那些数字的最小数字。

第一个c后面有一个b,为一对逆序对,所以c应填大于1的最小值2。后面的c应填1。

正确性的证明:

首先,对每个新加入的字母x,如果有小于x的字母y在x后面出现,那么x的数字一定大于y的数字。这保证了逆序对<x,y>一定能够进行交换。因此所有逆序对都能得到交换。

至于怎么证它的最优性,我还不会= =,但是大概可以意会出来XD

然后上面这个算法抽象出来就是两种操作:

一开始有数组(a),初始值均为0。

1.给出(i),查询区间([i,n])的最大值

2.给出(i)(x),更新(a_i=x)

用什么去搞就不用我多说了8

F

先把每个约束条件((a,b,v))拆成((S,v)),其中(S)是从(a)(b)的边的集合。我写了个巨丑无比的LCA,可能有别的写法。

把约束条件按边权大小排序,从大到小处理。假定当前边权是v,其对应若干条路径,这些路径组成的边集为({l_1,l_2,...,l_k}),则需把这些边中还没有赋权的边全部赋权v,因为:

1.如果把已经赋权的边更改为更小的这个v,则不满足前面处理过的条件;

2.如果把还没赋权的边不赋权v而是留着,则它可能会被之后的约束条件赋成一个更小的权,不满足这个约束条件;

3.如果把还没赋权的边赋成一个大于v的值,可行,但是代码实现不太简单。

这样能保证我造出来的树对每个约束条件((S,v)),满足(S)的所有边权都(geq v)。接下来只需直接check每个条件就能知道是否合法了。为什么?

这个方法每条边最多只会被赋值1次,在约束条件中的边也一定会被赋值。直接check等价于对每一层边权v,去check是否每一个约束条件都被满足,这又等价于check每一层边权v中,对每个约束条件,是否都有至少一条边被赋值为v。

举个例子:

4
1 2
2 3
3 4
3
1 2 5
3 4 5
2 4 3

先处理(val=5,S={(1,2),(3,4)}),把这两条边都赋值5。

再处理(val=3,S={(2,3),(3,4)}),把((2,3))赋值3。结束。

后记

这个div3打得我属实没劲,主要还是我容易把代码敲的太复杂。。。尤其是F,我敲了130多行,不太能理解60行以内的代码是怎么敲出来的,可能做法也不太一样吧。

system test还没过,万一我代码炸了 回来再改。。。

以上是关于Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #617 (Div. 3)

Codeforces Round #617 (Div. 3)

Codeforces Round #617 (Div. 3)

Codeforces Round #617 (Div. 3)

Codeforces Round #617 (Div. 3)

Codeforces Round #617 (Div. 3) A