比赛连接

G. Snake Rana

Old Macdonald wants to build a new hen house for his hens. He buys a new rectangular area of size N by M. The night before he builds the hen house, snake Rana devises an evil plan to plant bombs in K distinct cells in the area to kill the hens and eat them for dinner later.
The morning of, Old Macdonald notices that each of the K cells, where snake Rana planted a bomb, have a marking on them. That won’t stop him though, all he must do is build the hen house in an area with no bombs.
Assume that rows are numbered from top to bottom, and columns are numbered from left to right. Old Macdonald now wants to know the number of ways he can choose sub-rectangles of top left coordinates (x1, y1) and bottom right coordinates (x2, y2) (x1 ≤ x2) (y1 ≤ y2) such that there are no bombs in the sub rectangle.

Description

一个 n * m 的矩阵包含 k 个炸弹,统计不包含炸弹的子矩阵个数。

Solution

计算子矩阵数目:
对于 n * m的矩阵,一共有 n * (n + 1) / 2 * m * (m + 1) / 2 个,也就是等差数列
∑i=1ni∗∑j=1mj\sum_{i=1}^{n}i \ast \sum_{j=1}^{m}j i=1∑n​i∗j=1∑m​j
计算在 n * m 的矩阵中,包含任意一个子矩阵的所有矩阵数目为 up * left * (n + 1 - right) * (m + 1 - down) ,其中 up、down、left、right 代表当前子矩阵的上下左右边界位置。

容斥原理:
要计算几个集合并集的大小,首先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分。

可以简化理解为 奇加偶减奇减偶加(具体情况具体分析)

对于本题来说,首先计算出整个矩阵的所有子矩阵数目(n、m的前缀和乘积),然后分别减去包含一个炸弹、两个炸弹……的矩阵,利用二进制枚举炸弹状态(实在是妙)和容斥原理(本题是奇减偶加)避免重复相减的情况。

Code

#pragma GCC diagnostic error "-std=c++11"
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) x&(-x)
#define PII pair<int, int>;
#define mst(a, b) memset(a, b, sizeof(a))
#define FIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define rush() int T; scanf("%d", &T); while(T--)
using namespace std;
typedef long long LL;
//#define int LL
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const int Mod = 1e9 + 7;
const int MaxN = 1e5 + 5;struct node {int x, y;
}boom[25];int n, m, k;
LL ans;void solve() {for(int i = 1; i < (1 << k); i++) { // 利用二进制枚举炸弹的状态int u = INF, d = 0, l = INF, r = 0;int cnt = 0;for(int j = 0; j < k; j++) { // 判断当前状态i有哪些炸弹(第j为1说明当前状态下有第j个炸弹if(i & (1<<j)) { // 判断第j位是否为1,为1说明有炸弹cnt++;u = min(u, boom[j].y);d = max(d, boom[j].y);l = min(l, boom[j].x);r = max(r, boom[j].x);}}if(cnt) {LL res = 1LL * u * l * (n+1-r) * (m+1-d);if(cnt & 1) ans -= res; // 容斥原理else ans += res;}}
}int32_t main()
{int t; scanf("%d", &t);while(t--) {scanf("%d %d %d", &n, &m, &k);for(int i = 0; i < k; i++) scanf("%d %d", &boom[i].x, &boom[i].y);ans = 1LL * n * (1LL + n) / 2LL * m * (1LL + m) / 2LL;solve();printf("%lld\n", ans);}return 0;
}

【容斥】2017 ACM Arabella Collegiate Programming Contest相关推荐

  1. 2017 ACM Arabella Collegiate Programming Contest(solved 11/13)

    省选考前单挑做点ACM练练细节还是很不错的嘛- 福利:http://codeforces.com/gym/101350 先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于 ...

  2. 2017 ACM Arabella Collegiate Programming Contest G. Snake Rana GYM101350G

    先算一下总的子矩阵个数 总共最多只有20个点 状压一下然后枚举 容斥一下 把求出来的答案减去包含1个点的子矩阵再加上包含2个点的减去3个点的-- #include <iostream> # ...

  3. 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解

    F. Monkeying Around   维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...

  4. 2017 ACM Arabella Collegiate Programming Contest

    Gym101350A. Sherlock Bones 题目大意: 给定一个长度为 \(n\) 的 \(01\) 序列 \(\{s_n\}\),定义 \(F(i, j)\) 表示序列第 \(i\) 项到 ...

  5. 2017 ACM Arabella Collegiate Programming Contest E. Competitive Seagulls GYM101350E

    博弈经典套路 考虑把可选择的操作变成2个相同的 然后跟着对手操作 为奇数的时候选一个奇数把两边留出相同长度的白色 为偶数的时候选一个2把两边留出相同长度的白色 那么只有2 和 3 是不可以的 int ...

  6. 2017 ACM Arabella Collegiate Programming Contest(solved 9/13, complex 12/13)

    A.Sherlock Bones 题意: 给出长度为n的01串,问f(i,j)=f(j,k),(i<j<k)的i,j,k取值种数.其中f(i,j)表示[i,j]内1的个数, 且s[j]必须 ...

  7. 2017 ACM Arabella Collegiate Programming Contest A. Sherlock Bones GYM101350A

    把问题转换为求区间内1为奇数的区间有多少个 那么直接记录从1开始为奇数和偶数的区间有多少就算出这个了 但是有不合法的就是只有1个1的区间 所以再减一下 重复的再加回来 #include <ios ...

  8. 2017 ACM Arabella Collegiate Programming Contest F. Monkeying Around GYM101350F

    对单个点考虑 实际上每个点的结果只被最后的那种操作影响 那么处理一下每个点对应的最后一个操作种类 然后对每个种类都和对应的点都检查一下是否被操作了2次 转化成n个点 m个区间 多少点被覆盖>=2 ...

  9. 脑洞 博弈 E. Competitive Seagulls 2017 ACM Arabella Collegiate Programming Contest

    题目链接:http://codeforces.com/gym/101350/problem/E 题目大意:给你一个长度为n的方格,方格上面都被染色成了白色.每次染色都是选择白色的,假设目前选择的这块白 ...

最新文章

  1. Linux之因BASH造成的键盘错误和环境问题
  2. 【springboot】spring-boot-devtools 热部署 导致 mvn spring-boot:run 出现异常
  3. Effective C++ 条款44
  4. MFC中访问界面控件的两种方法
  5. java stringbuilder清空_Java中StringBuilder的清空方法比较
  6. 【Linux开发】linux设备驱动归纳总结(八):4.总线热插拔
  7. 不知道怎么办了,犹豫中……
  8. Unity3D基础29:消息发送
  9. linux 创建文件夹快捷方式
  10. 同济大学c语言程序设计答案,2020年同济大学道路与铁道工程考研真题试卷及试题答案,汽车理论及设计考研试题下载...
  11. Charles抓包工具实战教程(完结)
  12. 图解大数据 | 大数据生态与应用导论
  13. 电机与拖动知识点及试题
  14. 【io】io等待为什么引发cpu过高?
  15. Win64 驱动签名
  16. 使用Intent协议在webview中跳转三方app
  17. 实现Mac窗口最小化动画效果
  18. C++ 中的隐含 *this
  19. python实现划词翻译
  20. C# Speech学习笔记(一)

热门文章

  1. python获取qq好友ip_使用Python模拟登录QQ邮箱获取QQ好友列表
  2. 分别编写两个类Point2D,Point3D来表示二维空间和三维空间的点,使之满足下列要求
  3. 武汉创业者声讨网易:占用我们LOGO 还大张旗鼓做起销售
  4. 温故而知新:北桥和南桥
  5. 恒源云(GPUSHARE)_可构建AI的「AI」诞生?
  6. 当前普遍使用的微型计算机硬件,计算机应用基础电大考试试题
  7. 为什么模电这么难学?
  8. Excel数据的导入
  9. Django验证码*短信验证码之2-容联云通讯短信平台(联云通讯短信平台介绍、容联云通讯Python SDK、封装发送短信单例类)
  10. 镶嵌数据集工具小结(八)色彩平衡与接缝线 Ⅱ