Codeforces Round #423(div 2)

A

=w=

B

QvQ

C(并查集)

题意:

你需要根据要求构出一个字符串S

输入n个子串以及这些子串在S中出现的位置(有多个位置),输入数据保证不冲突

然后你根据这些已知子串去构一个字典序最小的S(也就是没涉及的位置填'a')

最终S的总长度<=2e6

分析:

不能直接暴力模拟,那样会TLE

给位置涂色的过程中将相邻的块用并查集合并,父亲是当前块最右边的那个位置

这样就可以保证每个位置最多遍历一次了

时间复杂度O(αlen)

D(构造)

题意:

给出n,k(n,k<=2e5)

可以构造出一个n个点的无根树,并且这个无根树叶子节点的个数是k

那么在这么些合法的树中,你需要找出一个树,叶子节点之间距离的最大值最小

分析:

我们希望它们之间的距离越平均越好

容易发现从根节点分出k个枝杈,然后每个枝杈尽可能平均地挂链,这样的树可以使得叶子节点之间距离的最大值最小

E(树状数组)

题意:

给出一个由A G C T组成的字符串S(|S|<=1e5)

有q(q<=1e5)个操作:

  操作1:将一个位置的字符修改

  操作2:读入l,r,e,e是一个长度<=10的字符串。字符串T=S[l..r],字符串E=eeeeeeeeeeee....,将T和E对比,计算有多少个位置i满足T[i]=E[i]

分析:

首先考虑没有修改操作

对于询问可以枚举e的每一位,那么就是询问一个等差序列与原串S对应位置的重合情况

可以对原串S预处理,数组c[id][i][j][]表示对于字符id,当公差是i的时候(明显公差<=10),首项是j的时候(j<=i),每个位置是否有字符id(0或者1)

那么对于询问其实就是求区间和,那么就求前缀和相减就行了

现在考虑修改操作

修改操作是:修改一个位置,询问区间和

所以直接BIT

时间复杂度O(4*10*10*len*log(len))

F(树上倍增)

题意:

给你一个n个点m条边的无向图,对于每条边都要回答询问

询问内容是:其他边边权不变,当前这条边边权可以改变,要想要在所有MST里都存在这条边,那么这条边的边权最大可以改为多少?如果无论改成多少这条边必存在于所有MST中,则此位置的答案是-1

n,m<=2e5

分析:

可以先求出一个MST,然后对所有边分类,一类是不在这个MST上的,另一类是在这个MST上的

对于不在MST上的边,容易发现答案就是树上两点之间最大值-1,这里直接倍增就行,维护fa[i][j]和max[i][j]

比较难处理的是在MST上的边

想法一:重构树(X)

想法二:断掉这条MST上的边后,原来的树变成了两个联通块,有一些不在树上的边连接着两个联通块,那么答案就是这些边的最小值-1(√)

想法二是可行的,那么如何操作呢?

容易看出来可以预处理考虑每条不在树上的边,它可以将树上的一段区间全部取min,当然树链剖分是可行的

实际上这里的取min更新倍增也可以做,而且更快更便捷

对于一个不在树上的边(u,v),可以在树上u,v之间走,维护对应的min[i][j]

然后将min[i][j]逆着倒推,就可以保证树上每个点和其每级父亲间的min都能更新出来

时间复杂度O(nlogn)

原文地址:https://www.cnblogs.com/wmrv587/p/7157522.html