文章目录
简单
G - Snake Rana
传送门
题意:有 n * m 的矩阵(n < 1e9, m < 1e9),有 k 个地雷(k <= 20),给出每个地雷的坐标,问有多少子矩阵没有地雷
做法:n * m 的矩阵种子矩阵的数量是 C(2 , n + 1) * C(2 , m + 1) ——从 n + 1 条边和 m + 1 条边里各选两条
用集合的角度看待,那么一个可以将整个矩阵分为
没有炸弹的矩阵集合
有1个炸弹的矩阵集合
有2个炸弹的矩阵集合
有3个炸弹的矩阵集合
...
有k个炸弹的矩阵集合
集合和集合之间会有重合的部分,所以是容斥原理
所以:没有炸弹的集合 = 全集 - 有一个 + 有两个 - 有三个 + 有四个...
那么现在的问题是如何去求这些集合,k 只有 20,所以可以考虑状态压缩,十进制转 k 位二进制,第 i 位为 1 代表
具体写法
for(int j = 0; j < k; j ++ )
{
if(i >> j & 1)
{
x1 = min(x1, a[j].first);
y1 = min(y1, a[j].second);
x2 = max(x2, a[j].first);
y2 = max(y2, a[j].second);
cnt ++ ;
}
}
LL res = (LL)x1 * (n - x2 + 1) * y1 * (m - y2 + 1);
如果 cnt 为奇,全集 - res
如果 cnt 为偶,全集 + res