其他分享
首页 > 其他分享> > POI2004 选做

POI2004 选做

作者:互联网

POI2004

Bzoj2066 Gra

简要题意: 长度为 \(m\) 的整数数轴上有 \(n\) 个坐标不同的棋子,保证棋子初始时不在 \(m\),两人轮流移动,每次将一个棋子移动到右边第一个空位置上,将棋子移动到 \(m\) 的人胜利,问先手必胜时第一步有多少种移动方法。

数据规模: \(n \le 10^6,\,m \le 10^9\)。

题解: 先考虑从结束状态往前推。显然当 \(m-1\) 处有棋子时先手必胜,所以两人都不希望自己将棋子移动到 \(m-1\)。如果 \([m-n-1,m-2]\) 内均有棋子,则下一步对方不得不将棋子移动到 \(m-1\),故此时先手必胜。于是胜利条件转化为将所有棋子移动到 \([m-n-1,m-2]\)。

下面考虑对每轮的操作进行转化。注意到每次操作相当于选出一些连续棋子的后缀,将其整体右移一格。考虑设 \(num_x\) 表示右边有 \(x\) 个空格子的棋子数量,即选择 \(k \in [1,num_x]\),并对其进行 \(num_x \leftarrow num_x - k\) 和 \(num_{x-1} \leftarrow num_{x-1}+k\) 的操作。这是个非常经典的阶梯 Nim 博弈,其 SG 函数为所有奇数 \(x\) 的 \(num_x\) 的异或和。

预处理当前状态的 SG 函数,枚举第一步的移动并简单维护下新的 SG 函数即可。

Bzoj2067 Szn

简要题意: 给定一棵树,边的长度为 \(1\),求使用最少的链的数量使得所有边被且仅被覆盖一次,并同时要求最长链最短。

数据规模: \(n \le 10^4\)。

题解: 第一问的答案为 \(1+\sum\frac{deg_u-1}{2}\),可以看作是将每个节点的儿子两两配对,剩下的链延伸到父亲。

第二问可以二分答案 + 判断,也是经典的老套路了。对整棵树进行 dfs,将子树向上延伸的链的长度两两匹配。在失配的链中找到最短的那个向父亲延伸,剩下的链直接断开,代码也非常好写,总复杂度 \(O(n\log^2n)\),因为要排序。

注意在匹配儿子延伸上来的链的时候要从大往小匹配,否则是错的,但是数据没有卡。这里提供一组 hack 数据。

hack 数据
15
1 2
2 3
3 4
4 5
5 6
1 7
7 8
7 9
9 10
7 11
11 12
12 13
13 14
14 15

应当输出

2 7

Bzoj2068 Szp

简要题意: \(n\) 个特工,每个特工都监视着另一个特工,问最多能选多少个特工使得每个被选择的特工都被某个没被选择的特工监视着。

数据规模: \(n \le 10^6\)。

题解: 只需在基环树上进行简单的 dp 即可。没什么技术含量,不建议写。

Bzoj2069 Zaw

简要题意: 给定一张无向图,每条边正着走和反着走的边权不同,求从点 \(1\) 开始不重复经过边并回到 \(1\) 的最短路。

数据规模: \(n \le 5000,\, m \le 10^4\)。

题解: 暴力枚举第一条边后跑可以过,但有更好的做法。假设已经确定走第一条边 \((1,s)\) 和最后一条边 \((t,1)\),可以直接将与 \(1\) 有关的边删去后跑最短路,因为最短路一定不会重复经过一条边。由于不能经过同一条边多次,所以要确保 \(s \neq t\)。

既然有 \(s \neq t\),就意味着 \(s\) 和 \(t\) 的二进制表示中至少有一位不同。于是可以枚举二进制位 \(k\),将第 \(k\) 位为 \(0\) 的作为源点,为 \(1\) 的作为汇点,跑最短路,反过来同理,这样就保证了源点 \(s\) 和汇点 \(t\) 一定不相同。因此,可以使用二进制分组,在 \(O(m\log^2m)\) 的时间复杂度内完成。

Bzoj2075 KAG

简要题意: 原题的题面描述已经够清楚了。

数据规模: \(n \le 10^4,\, m \le 10^5\)。

题解: 为了表述方便,我们称原图的边为黑边,原图的补图的边为白边。

注意到,如果对于一张导出子图,如果其是通过图 \((1)\) 的方式合并,则黑边一定形成 \(> 1\) 个连通块;如果是通过图 \((2)\) 的方式合并,则白边一定形成 \(> 1\) 个连通块。而由于补图的性质,黑边和白边不可能同时形成 \(> 1\) 个连通块。

所以考虑分治。对于一张导出子图,计算其黑色和白色的连通块个数。如果二者都 \(= 1\),直接返回 NIE。否则,根据对应的合并方式分成几个新的导出子图进行递归。

我们希望,可以快速计算出黑色和白色的连通块。黑色是容易计算的,直接 bfs 就可以 \(O(n+m)\) 地求出。问题在于白色连通块,要判断两个白色连通块 \(S_1\) 和 \(S_2\) 之间是否有白边,不妨暴力枚举 \(u \in S_1\) 和 \(v \in S_2\),判断 \((u,v)\) 是否为白色。这样的复杂度是正确的,因为如果 \((u,v)\) 为黑色,那么相当于枚举了所有的黑边,是 \(O(m)\) 的;否则 \((u,v)\) 为白色,那么直接将 \(S_1\) 与 \(S_2\) 合并,最多合并 \(O(n)\) 次,复杂度也是 \(O(n+m)\) 的。

最后便是递归次数的计算。注意到,按照黑色连通块分裂,则最多递归 \(O(n)\) 层;按照白色连通块分裂,则每次分裂都会使得 \(O(n)\) 条黑边被去掉,所以总的递归次数是 \(O(\min(n,m/n))\),即 \(O(\sqrt m)\) 的。

综上所述,此题可以在 \(O((n+m)\sqrt m)\) 的时间复杂度内求得答案。代码需要精细实现一下,比较难写(指需要十个甚至九个链表)

Bzoj2078 Wys

简要题意: 给定 \(n\) 个边不相交的多边形,每条边平行或垂直于 \(x\) 轴,顶点坐标按照逆时针给出,其包含关系形成树形结构。求树形结构的最大深度。

数据规模: \(n \le 4\times 10^4\),点数 \(|V| \le 2\times 10^5\)。

题解: 类似于这道题,对于此类将多边形的嵌套关系转成树形结构的问题,比较套路的做法是在当前多边形的任意边缘处添加一条向外的射线,并找到其经过的第一个多边形。我们设当前多边形为 \(u\),射线所经过的第一个多边形为 \(p\),则 \(u\) 和 \(p\) 有以下两种关系:

  1. \(p\) 是 \(u\) 的父亲。其充要条件是 \(u\) 被 \(p\) 所包含。
  2. \(p\) 是 \(u\) 的兄弟。其充要条件是 \(u\) 不被 \(p\) 所包含。

下面问题转化为判断 \(u\) 和 \(p\) 是否产生包含关系。对于每个多边形,我们按照逆时针的顺序加入若干条有向边,这样可以根据射线扫到的 \(p\) 的边的方向来判断射线是否在多边形 \(p\) 内,进而得到 \(u\) 和 \(p\) 的包含关系。

具体到这道题目,由于题目条件中每条边都平行于坐标轴,所以不难想到直接提取出所有跟 \(y\) 轴平行的边进行扫描线,维护每一时刻每个点左边的第一条边对应的多边形以及其方向即可,最后直接在树上求出最大深度即为答案。时间复杂度 \(O(|V|\log |V|)\),代码很好写。

标签:10,连通,选做,多边形,POI2004,num,le,棋子
来源: https://www.cnblogs.com/yaoxi-std/p/16690716.html