IOI2020第一轮选拔模拟4(线性基、点分治)

今天的题也很难,目前只改出了两题。

T1:这题要用到一个叫线性基的工具。

首先我们发现3^b给予我们一个贪心的思路:一定是要优先满足b较大的列。

紧接着就有一个做法了:从大到小枚举b,判断计算当前b的最大贡献。如果b有+1而没有-1,那么就判断一下3^b是否可行。有-1而没有+1同理。注意有+1也有-1时两列都为0和两列都为1的情况是同理的,在这种情况下我们可以定义限制为两列异或起来的值为0。

至于判断当前情况是否可行,我们可以用线性基来做。具体做法就是用线性基判断一下当前的n个数能不能从中选出一些使得异或值为我们想要的数。

T2:题解待更新。

T3:这题是一个点分治。

首先套上点分治的模板,每一层就代表一维。

然后对于每一次找出的重心,我们把它的儿子分成大小相对均匀的两部分,设它们分别为A和B。

接着算出A和B中每一个点到重心的距离,接着指定A到重心的边权在当前这一维中乘1,B到重心的边权在当前这一维中乘-1。这样我们就保证了每一个A集合中的点到B集合中的点的距离是合法的。

接着我们先断掉重心到B的连边,然后递归处理A+重心;再断掉重心到A的连边,递归处理B+重心。这样一直处理下去,就保证了所有的点对都是合法的。

最后我们把每一位按照边的权值来求出最终的答案数组。

下面要证明这个方法是对的:

1、算出来的数组的正确性是有保证的,即不会出现max>dis的情况。关于这个我们可以分维讨论,在这之前或之后的差值都不会比边权的和大。这个很难讲,但是画一下图就明白了。

2、每一次至少分出n/3的大小,也就是说最多剩下n*2/3的大小,所以最终的维数不会超过16(即1000不断乘2/3直至为0的次数)。

注意+1或-1的边是有向的。

发布了149 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chiyankuan/article/details/103463602