HNOI2012解题报告
Author: Pengyihao
Day1 T1 双十字
思路
因为矩阵总的大小不超过 \(1000000\),所以我们可以预处理往左最多能延续多少,往右、往上、往下……
然后我们考虑枚举双十字中间线所在的列。
枚举下面这根横线所在的行。
然后对于这根横线形成的双十字的数量有影响的行,一定在其之上并且长度短于它。
于是对于每段连续的 \(1\),我们维护一个 \(splay\)。
\(splay\) 的关键字键值为左右延伸的长度,然后记录每个点往上扩展的长度以及自身的长度能够给予的贡献。
这个贡献可以求一下子树的和。
那么每次计算下面这根横线的贡献的时候,直接找到它在 \(splay\) 中的位置,把它左边、右边的区间提取出来,计算贡献即可。
注意必须在第 \(i\) 行的时候插入第 \(i-2\) 行,因为两根横线不相邻。
代码
|
|
Day1 T2 与非
思路
首先可以发现一个性质——NAND操作可以构成所有的位运算,这个手玩一下就出来了。
然后对于二进制的某两位,我们发现如果对于每一个操作数,他们的这两位都相同,那么不论怎么运算最后肯定还是相同的。
除了这种限制之外,就没有其它限制了。
意思是说,如果在必定相同的两位之间连一条边,那么会形成一个个联通块。联通块与联通块之间两两对于答案的贡献是独立的。
联通块可以用并查集维护。
于是就可以答案进行数位DP辣!!
对于答案的第 \(i\) 位,它的取值会影响一个联通块的取值。
我们从高到低地做,如果边界的该位上为 \(1\),那么我们取 \(0\) 的话答案就要加上 \(2^p\),其中 \(p\) 是尚未确定的联通块个数。
其余的类似。
代码
|
|
Day1 T3 排队
思路
首先放男同学,有 \(n!\)。
然后放老师,可以放到一起或分开放,方案分别为 \(n!\times P_{n+1}^2\times P_{n+3}^m\),和 \(n!\times2(n+1)\)。
最后放女同学。如果老师放在一起了,那么就要放一个女同学在老师中间;否则把老师看作男同学。
总方案为
\[n!\times(P_{n+1}^n\times P_{n+3}^m + 2(n+1)\times P_{n+2}^{m-1}\times m)\]
代码
|
|
Day1 T4 矿场搭建
思路
首先双联通缩点,然后对于每个联通块,只需要每个叶子节点放一个出口就行了(不能放割点)。
方案个数的话乘法原理就好了。
注意只有一个双联通分量的情况要特判!!
代码
|
|
Day2 T1
这是一道计算几何的题目。
因为我还没有进行这个专题,所以我跳过了这道题目。
Day2 T2
这是一道计算几何的题目。
因为我还没有进行这个专题,所以我跳过了这道题目。
Day2 T3
思路
这个题目是一道 \(splay\) 的启发式合并的模板题。
只需要从小的合并到大的中间就可以了。
代码
|
|
Day2 T4 集合选数
思路
考虑一张表,将 \(1\) 在左下角。
满足一个性质:对于一个格子,它的右边的格子里的数字是它的 \(3\) 倍,上面的格子里的数字是它的 \(2\) 倍。
于是问题转化为在格子中选不相邻的数的方案数。
表的长宽不会很大,是 \(log\) 级别的。
可能有很多张不相交的表。
状压dp就好了。
代码
|
|