[Russian Code Cup 2017 - Finals [Unofficial Mirror]]简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢。
Div1难度+ACM赛制 和几个大佬组队逛了逛
A.给一个大小为n的集合ai(1<=ai<=1000000),要求你构造一个大小同样为n且值域相同的数组b,满足ai+bj没有相同的。
T<=100 n<=100
暴力,从小到大枚举过去,可以选就选。
复杂度T(n^3+10^6)
B.给你n个字符串,要求你选一些前缀构成一个前缀集合,满足不存在两个前缀,其中一个去掉首字母之后变成另一个。求集合最大大小。
n<=10^6 总长度<=10^6
首先建trie树,然后暴力找出最多O(n)条不能同时存在的条件。
发现这些条件构成一棵树,所以求树的最大点独立集就行了。
C.给你n个数字,问有多少种排列,满足把数字接起来之后是11的倍数。
n<=2000 ai<=10^9
接一个数相当于乘上10的某一次方然后加上一个数。
发现10的次方膜11意义下只有两种取值,而且是1和10(-1),把10的那些拿出来,这些数字会把数字序列分城一些段,每一段里面数字的贡献是1或者-1,并且两者分别的段数已知。
首先求10的那些的排列数,然后考虑把1的那些填到每一段里面,有一个dp:
f[i][j][k]表示前i个1的数,j个填到了贡献是1的段里面,现在总和膜11是k的方案数。然后就没啦。
复杂度(11n^2)
D.给一棵大小为n的数和m条链,每条链有一个价值。你要选择一些链,满足这些链不相交且价值和最大。
n,m<=2*10^5
考虑一个dp,f[i]表示只选在i的子树内的链的最大价值,然后每条链放到lca处做。
对于每个点,考虑用以这个点为lca的链来转移,那么选择这条链之后还能选的是若干个子树,现在我只需要快速求这些子树的f[]的和就行了。
那么考虑树剖,然后每个点维护它的所有轻儿子的f[]的和,这样可以配合线段树在log^2时间内求出这个信息,这样我们就做完了。
代码cf找咯