Educational Codeforces Round 83[CF1312]

链接

这场比赛问题简单,但还是暴露的很多问题的。

G和E都花了太长时间了。证明自己的思维还是太慢。

Problem A

求正 $n$ 边形中选出 $m$ 个顶点是否能组成正 $m$ 边形。

显然:$m|n$。

Problem B

构造一种方案,将数组重排后,使得不存在 $i-a_i = j-a_j$ 的情况。

显然从大到小输出即可。

求方案数?

Problem C

一个数组,可以选择一个 $m$,然后对于每个 $i\in[1,m]$,将数组的某个位置减去 $k^i$。问是否存在一个 $m$,使得数组全为 $0$?

从大到小暴力即可。

Problem D

太长了,懒得写了。

先特判 $n=2$ 的情况。

枚举最大的那个的值以及位置,再枚举左右相等的那个点谁,然后组合数化简一下即可。

Problem E

题意

一个数列 $a$,每次可以将两个相邻且相等的数合成一个,权值加 $1$。

问数列 $a$ 最短能变成多少。

$n\leq 500$

题解

区间DP,看区间 $[i,j]$ 能否合成一个数 $k$,然后再一次 DP/bfs 就可以了。

时间复杂度 $O(n^3)$。

Problem F

留坑。。。

Problem G

为什么最后这道题这么简单啊。。。

题意

太长了,不写了。

题解

设在 $S$ 中的点为关键点。

显然考虑按dfs进行DP,设 $f_i$ 表示到 $i$ 这个节点的最短时间, $d_i$ 为深度,$s_i$ 为到考虑到当前的dfs序为止时,$i$ 的子树中的有多少个关键点。

若点 $i$ 不是关键点,有:$f_i=\min{f_j+d_i-d_j}$,其中 $j$ 为 $i$ 祖先。

若点 $i$ 是关键点,就会多一种转移: $f_i=\min{f_j+s_j}$,其中 $j$ 为 $i$ 祖先。

第二种转移需要支持区间 $+1$。即遇到一个关键点的时候需要令 $s_j$ 加上 $1$。

因此只需要实现一个单点覆盖和区间加,查询区间最大值的数据结构即可。

线段树/set/可删堆可以很轻松的维护。

时间复杂度 $O(n\log n)$。