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)