【比赛】【SMOJ 2019.3.24】

\(\mathrm{T1}\)

最小

这个很容易想的啊,我们在数轴上圈定一块长度为\(\mathrm{N}\)的连续区间,则移动次数就是\(\mathrm{N}-\texttt{区间内的棋子个数}\)。(可以证明不需要其他操作了)

唯一一个特判就是这样的:所有棋子分成两堆连续的部分,且一堆有\(1\)个棋子,另一堆有\(\mathrm{N}-1\)个棋子

这个要分两种情况:

  1. 一步一步移过去
  2. 像中国跳棋一样把大的那堆棋子的哨兵拉过来挖一个坑,小的那堆再填坑。

两种方案取个最小值即可。

最大

这个更简单,就一个个滚过去就好了。

就是要看看是从左边开始还是右边开始。

\(\mathrm{Code}\)


\(\mathrm{T3}\)

又是一道容斥原理题。

话说这一题的暴力怎么打怎么出问题,不知道其他dalao们是怎么过的。

先假设\(1\)号节点为整棵树的根。

我们先构思一个很神奇的状态:\(f(tn,gn)\)表示将以树上节点\(tn\)为根的子树放到图上,且\(tn\)和图上的节点\(gn\)相对应的方案数。

然后我们可以直接暴力搞出每个儿子的方案数并相乘,也就是说:

\[f(tn,gn)=\prod\limits_{tv\in son(tn)}\sum\limits_{gn\rightarrow gv}f(v,gv) \]

如果你真的这么写,就会发现输出比答案大了很多,因为这样算出来的方案数有很多都重复覆盖了图上的节点,所以我们才需要用容斥,将那些没有覆盖完所有图上节点的方案数减去,再把多减去的加上……

就是这样了。

\(\mathrm{Code}\)

posted @ 2019-08-01 11:24  info___tion  阅读(108)  评论(0编辑  收藏  举报