UVA - 11983 Weird Advertisement (线段树求并面积)
来源:互联网 发布:艾瑞咨询好吗 知乎 编辑:程序博客网 时间:2024/05/16 06:45
Description
G
Weird Advertisement
Renat Mullakhanov (rem), one of the most talented programmers in the world, passed away on March 11, 2011. This is very sad news for all of us. His team went to ACM ICPC World Finals - 2004, placed 4th and won gold medals. He really was a great programmer. May he rest in peace. This problem is dedicated to him.
2DPlaneLand is a land just like a huge 2D plane. The range ofX axis is 0 to 109 and the range ofY axis is also 0 to 109. People built houses only in integer co-ordinates and there is exactly one house in each integer co-ordinate.
Now UseAndSmile Soap Company is launching a new soap. That's why they want to advertise this product as much as possible. So, they selectedn persons for this task. Each person will be given a rectangular region. He will advertise the product to all the houses that lie in his region. Each rectangular region is identified by4 integers x1, y1, x2 andy2. That means this person will advertise in all the houses whosex co-ordinate is between x1 and x2 (inclusive) and y co-ordinate is between y1 and y2 (inclusive).
Now after a while they realized that some houses are being advertised by more than one person. So, they want to find the number of houses that are advertised by at leastk persons. Since you are one of the best programmers in the city; they asked you to solve this problem.
Input
Input starts with an integer T (≤ 13), denoting the number of test cases.
Each case starts with a line containing two integers n (1 ≤ n ≤ 30000), k (1 ≤ k ≤ 10). Each of the nextn lines will contain 4 integers x1, y1, x2, y2 (0 ≤ x1, y1, x2, y2 ≤ 109, x1 < x2, y1 < y2) denoting a rectangular region for a person.
Output
For each case, print the case number and the total number of houses that are advertised by at leastk people.
Sample Input
Output for Sample Input
2
2 1
0 0 4 4
1 1 2 5
2 2
0 0 4 4
1 1 2 5
Case 1: 27
Case 2: 8
题意:给你n个矩形,求覆盖大于等于k的点数
思路:将右上角的点x,y都加一就能转换成求并面积了,还是上面的边标记1,下面的边标记-1,传统的线段树求并面积,容易错的地方是在更新的时候,引用胡浩大大的一句话:这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方可以自己好好的琢磨一下
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#define lson(x) ((x) << 1)#define rson(x) ((x) << 1 | 1)#define ll long longusing namespace std;const int maxn = 60005;const int M = 160010;int k;struct Seg {int l, r, h, s;Seg() {}Seg(int a, int b, int c, int d) {l = a, r = b, h = c, s = d;}bool operator <(const Seg &tmp) const {if (h == tmp.h)return s > tmp.s;return h < tmp.h;}} p[maxn<<2];int sum[11][M<<2];int cover[M<<2];int w[M<<2];;void pushup(int pos, int l, int r) {for (int i = 0; i <= k; i++)sum[i][pos] = 0;if (cover[pos] >= k) {sum[k][pos] = w[r+1] - w[l];return;}if (r == l) {sum[cover[pos]][pos] = w[r+1] - w[l];return;}int tmp = 0;for (int i = 0; i <= k; i++) {if (i + cover[pos] < k)sum[i+cover[pos]][pos] = sum[i][lson(pos)] + sum[i][rson(pos)];else sum[k][pos] += sum[i][lson(pos)] + sum[i][rson(pos)];}for (int i = 1; i <= k; i++)tmp += sum[i][pos];sum[0][pos] = w[r+1] - w[l] - tmp;}void update(int L, int R, int l, int r, int pos, int op) {if (L <= l && R >= r) {cover[pos] += op;pushup(pos, l, r);return;}int m = l + r >> 1;if (L <= m)update(L, R, l, m, lson(pos), op);if (R > m)update(L, R, m+1, r, rson(pos), op);pushup(pos, l, r);}int search(int x, int r) {int l = 0;while (l <= r) {int m = l + r >> 1;if (w[m] == x)return m;else if (w[m] < x)l = m + 1;else r = m - 1;}return -1;}void build(int l, int r, int pos) {sum[0][pos] = w[r+1] - w[l];if (l == r)return;int m = l + r >> 1;build(l, m, lson(pos));build(m+1, r, rson(pos));}int main() {int t, n, m, cas = 1;scanf("%d", &t);while (t--) {scanf("%d%d", &n, &k);memset(cover, 0, sizeof(cover));memset(sum, 0, sizeof(sum));int tot = 0;int a, b, c, d;for (int i = 0; i < n; i++) {scanf("%d%d%d%d", &a, &b, &c, &d);c++, d++;p[tot] = Seg(a, c, b, 1);w[tot++] = a;p[tot] = Seg(a, c, d, -1);w[tot++] = c;}if (k > n) {printf("Case %d: 0\n", cas++);continue;}sort(w, w+tot);sort(p, p+tot);int cnt = unique(w, w+tot) - w;build(0, cnt-1, 1);ll ans = 0;for (int i = 0; i < tot-1; i++) {int l = search(p[i].l, cnt-1);int r = search(p[i].r, cnt-1)-1;update(l, r, 0, cnt-1, 1, p[i].s);ans += (ll)(sum[k][1] * (ll)(p[i+1].h - p[i].h));}printf("Case %d: ", cas++);printf("%lld\n", ans);}return 0;}
- UVA - 11983 Weird Advertisement (线段树求并面积)
- UVA 11983 Weird Advertisement (线段树+矩形面积并)
- UVA 11983 - Weird Advertisement(线段树)
- UVA 11983 Weird Advertisement --线段树求矩形问题
- uva 11983 - Weird Advertisement(线段树)
- UVA 11983-Weird Advertisement-k次以上覆盖矩形面积(线段树+扫描线)
- UVA 11983 Weird Advertisement(线段树扫描线)
- UVA 11983 Weird Advertisement
- Weird Advertisement - UVa 11983 扫面线求重复K次的面积
- uva 11983 Weird Advertisement(扫描线)
- 【扫描线】【线段树】UVa11983 Weird Advertisement
- uva11983 - Weird Advertisement 矩形面积并 重叠大于等于K次的面积
- [Uva11983][线段树][扫描线]Weird Advertisement[好题]
- HDU 1542 Atlantis(线段树求矩形面积并)
- 求矩形并的面积(线段树)【模板】
- HDU 1542 Atlantis(线段树求矩形面积并)
- poj 1151(线段树求面积并)
- POJ 1389 求矩形面积并(线段树)
- java集合学习一
- 在AppDelegate自定义一个ViewController
- POJ 3259 Wormholes(SPFA)
- [Leetcode] Balanced Binary Tree
- 简单的理解unicode和utf-8的关系
- UVA - 11983 Weird Advertisement (线段树求并面积)
- Hibernate单向多对一级联删除引发的问题
- HDU2544,最短路
- V7 jar
- 【RPi树莓派使用指南】GPIO驱动方法
- UVA 10228 - Star not a Tree?(模拟退火)
- Nested Classes,Static Classes,Non-static Classes,Inner Classes,Local Classes,Anonymous Classes
- Android:实现手势滑动的事件处理方法
- HDU 4883 Best Coder Round 2 TIANKENG’s restaurant 题解