Processing math: 100%

[LibreOJ 2135][ZJOI2015]幻想乡战略游戏

竟然1A了蛤蛤蛤蛤蛤

这题用人话说就是给你一个不会动的树,让你求带权重心。

先解决一个问题:如果要求动态修改点权,并且要求多次询问求某点xni=1didist(i,x),怎么做?

很显然对于一个点x,对它造成贡献的点,可能是在以x为根的点分子树里的,也可能在x之外。但是一个不在该点分子树内的点要对x产生贡献,必须要经过x在分治树上的祖先。

所以我们可以考虑对每个重心,记录下它这个点分子树中所有点对该重心的贡献、对点分树上的父亲的贡献以及该点分子树的点权和。每次求答案时x所在的分治子树的贡献很好考虑,那考虑一下其分治树上祖先对x的贡献就行了。

那带权重心怎么求呢?如果我们把树的根变成带权重心,那么我们会发现越远离根则答案越劣。所以我们如果只往使得答案更小的地方走,那么最后一定会走到带权重心上。

我们考虑把这个过程放点分树上。从整棵树的重心开始往下走,每次如果发现有一条出边指向的点答案更好,那就往这个子结构(不是指向的点而是那个联通块的重心,否则时间复杂度不对)里走。最后走不动了,走到的点就是带权重心了。

求LCA我用的是O(logn)的树剖而不是O(1)搞法,但是跑的贼快(可能和树剖常数小有关?)。

吐槽一点,原题提到了每个点的度数不超过20,但是网上几乎所有OJ上该题的题面都没提到这一点……

代码:

[BZOJ 1095][ZJOI2007]Hide 捉迷藏

蛤蛤蛤我这题终于调出来了~(然后1A了)

点分树处女作。其实点分树的思想并不难理解,就是把点分的过程抽象化到一棵树上。

其实唯一比较烦人的就是点分树上的儿子给父亲的贡献要开一个堆处理……非常烦人。

代码(其中有海量本来拿来调试的代码,慎读):