[NEERC2016]Cactus Construction

tag:构造

一道很有意思的构造题


首先考虑树怎么做:

  • 叶子节点把颜色改为 \(2\)
  • 非叶子节点把颜色改为 \(3\)。然后先处理完所有儿子,再将所有儿子集合与当前点合起来。然后连 \(2,3\),即把所有儿子和当前点连起来。再改 \(2\)\(1\),改 \(3\)\(2\)

可以发现每个节点处理完后,都满足:

  • 当前点颜色为 \(2\)
  • 子树内所有其他点颜色为 \(1\)
  • 子树内所有边都已经连好了

所以如果是树的话,只需要 \(3\) 种颜色就够了


推广到仙人掌上,建出圆方树,对于圆点的操作和树一样,考虑方点(环)怎么处理。

设当前方点 \(x\),父亲为 \(y\)。那么找到 \(x\) 对应的环,顺次处理这个环。沿用之前的思路,我们保证每一个点处理完后颜色都为 \(2\),且集合内其他点颜色都为 \(1\)。于是我们依次合并两个相邻的儿子,设为 \(a,b\)

  • \(r\ a\ 2\ 3\)
  • \(j\ a\ b\)
  • \(c\ a\ 2\ 3\)
  • \(r\ a\ 3\ 1\)

这样操作后,就连了一条 \((a,b)\) 的边,而且让 \(a\) 的颜色改为了 \(1\)

但是问题来了,到了最后一步我们需要把这条链的头尾连起来,怎么办呢?

这个时候就用上第 \(4\) 种颜色了,对于第一个处理的节点,合并后我们不把它的颜色改为 \(1\),而是改为 \(4\)。这样的话是不会影响连这条链的过程的,而且最后做一次连 \(2,4\) 操作就可以把头尾连起来,然后再做一次改 \(4\)\(1\) 保证性质。


关于操作次数,此题 \(10^6=20n\),也就是说一个点能够进行 \(20\) 次操作,显然我们的操作数远达不到这个上限。


上述就是大体思路,不过这题细节十分多

细节1

在连链的时候,要分三类

  • 第一个点
    • \(r\ x\ 2\ 4\)
  • 第二个点
    • \(j\ x\ prv\)
    • \(c\ x\ 2\ 4\)
  • 其他点
    • \(r\ prv\ 2\ 3\)
    • \(j\ x\ prv\)
    • \(c\ x\ 2\ 3\)
    • \(r\ x\ 3\ 1\)

细节2

在具体实现方点的时候,假设方点 \(x\),父亲 \(y\)。那么可以把这个环除了 \(y\) 之外的点先连成一条链。根据构建过程,这根链满足头为 \(4\),尾为 \(2\),其余点为 \(1\)。所以可以做:

  • \(r\ \text{链}\ 2\ 4\)
  • \(j\ \text{链}\ y\)
  • \(c\ y\ 2\ 4\)
  • \(r\ y\ 4\ 1\)

这样就一下连了两条边。(如果当前 \(y\) 的颜色为 \(1\),则还需要一次操作把 \(y\) 的颜色改为 \(2\))

细节3

由于在实现方点的时候,我们会修改 \(y\) 的颜色。所以在处理圆点 \(x\) 的时候,如果有至少一个儿子是方点,就不执行改颜色的操作! 因为这样会把 \(y\) 集合中其他 \(1\) 改为 \(2\)(WA on 34)。当然也要特判没有方儿子的时候,做一次改颜色 \(1\)\(2\) 的操作。

代码

posted @ 2021-06-26 14:06  oisdoaiu  阅读(34)  评论(0编辑  收藏  举报