Codeforces Gym 101505D Orchard Division(离散化+树状数组+扫描线+二分)
来源:互联网 发布:国外通用航空软件 编辑:程序博客网 时间:2024/06/05 19:32
Orchard Division
orchard.c, orchard.cpp, orchard.c11, Orchard.java, orchard.py
Uncle Oliver isgoing to sell a significant part of his famous dwarf plum tree orchard. He isgoing to divide the orchard into two parts, sell the first one and keep theother one.
The trees wereoriginally planted in regular rows and columns forming a rectangular grid withthe same number of rows and columns. As years went by, Oliver removed manytrees which were weak or plagued by bugs so nowadays there is also a lot offree squares unoccupied by any tree.
Oliver hasdecided that he will keep exactly half of all the trees in the orchard.Moreover, he has few additional demands which, in his opinion, will ensure easymaintenance of his part in the future.
• The part Oliver is going to keep should be in theshape of a rectangle.
• A least one corner of the rectangle shouldcoincide with a corner of the orchard.
• The rectangle area should be as small aspossible.
Originally, eachtree was planted in the center of an imaginary square whose area was exactlyone square meter. Thus, the position of each tree can be described by thecoordinates of the square on which it is standing. The dividing fence betweenthe two parts of the orchard will run along the borders of the squares.
Input Specification
There are moretest cases. Each case starts with a line containing two integersM(1 ≤ M ≤ 109) and N (1≤ N ≤ 106) separated byspace. The orchard side length in meters is expressed byMand the number of trees in the orchard is expressed by N. Next, there areNlines, each line specifies xand y coordinates of one tree inthe orchard. The coordinates are separated by space. For simplicity reasons, weassume that the coordinates are zero based, so the coordinates of the squaresin the corners of the orchard are (0,0),(0,M−1),(M −1,M−1),(M−1,0). All coordinate pairs (x,y) in one test case are unique.
Output Specification
For each testcase, print a single line with one whole number A denoting the minimum possible area in square meters of uncleOliver’s part of the orchard. If it is not possible to divide the orchardaccording to Oliver’s demands print “-1”. Note that the output value might not fit into 32-bit integer type.
Sample Input
6 8
4 5
1 4
0 3
5 3
1 2
3 2
3 1
2 0
3 3
2 0
1 1
0 2
2 2
0 0
1 1
Output for Sample Input
12
-1
1
【思路】
首先数据范围很大,点数却没那么大,也就需要先对坐标进行离散化。然后对所有的点进行双关键字排序,接下来进行扫描线操作。第一遍扫描线从高到低扫,维护横坐标出现的的次数,并查询前缀和为总点数一半的那个点的位置,以及后缀和为总点数一半的那个点的位置,可以据此算出面积;第二遍从低到高扫,也是一样分前缀和后缀来算。面积最小的那个正是答案。维护和查询横坐标出现次数用树状数组,由于sum函数具有递增性,查找某个点的位置时可以二分查找。这里两个优化中的一个不做都会TLE,另外二分时应该注意,找前缀的那次要尽可能找左边的点,找后缀的那次要尽可能找右边的点。
【代码】
#include <cstdio>#include <cstring>#include <algorithm>#include <map>using namespace std;const int MAXN = 1e6 + 5;const long long INF = 0x3f3f3f3f3f3f3f3f;struct point { long long x, y; bool operator<(const point &another) const { if (y == another.y) return x < another.x; return y < another.y; }};int n, ord;long long m;int a[MAXN];long long num[MAXN];point p[MAXN];map<long long, int> id;int lowbit(int x){ return (x & -x);}void modify(int x, int num){ while (x <= ord) { a[x] += num; x += lowbit(x); }}int sum(int x){ int ans = 0; while (x > 0) { ans += a[x]; x -= lowbit(x); } return ans;}bool cmp(const point &a, const point &b){ return a.x < b.x;}int binsearch_l(int num){ int l = 1, r = ord, ans; while (l + 1 < r) { int mid = (l + r) >> 1; if (sum(mid) < num) l = mid + 1; else r = mid; } if (sum(l) == num) ans = l; else if (sum(r) == num) ans = r; else ans = 0; return ans;}int binsearch_r(int num){ int l = 1, r = ord, ans; while (l + 1 < r) { int mid = (l + r) >> 1; if (sum(ord) - sum(mid - 1) > n / 2) l = mid + 1; else r = mid; } if (sum(ord) - sum(r - 1) == n / 2) ans = r; else if (sum(ord) - sum(l - 1) == n / 2) ans = l; else ans = 0; return ans;}int main(){ while (scanf("%lld %d", &m, &n) == 2) { for (int i = 1; i <= n; i++) { scanf("%lld %lld", &p[i].x, &p[i].y); p[i].x++; p[i].y++; } if (n % 2 == 0) { sort(p + 1, p + 1 + n, cmp); ord = 0; id.clear(); for (int i = 1; i <= n; i++) if (!id.count(p[i].x)) { id[p[i].x] = ++ord; num[ord] = p[i].x; } sort(p + 1, p + 1 + n); int index; long long ans = INF; memset(a, 0, sizeof(a)); index = 1; while (index <= n) { while (index + 1 <= n && p[index].y == p[index + 1].y) { modify(id[p[index].x], 1); index++; } modify(id[p[index].x], 1); if (index < n / 2) {index++; continue;} int pos; pos = binsearch_l(n / 2); if (pos != 0) ans = min(ans, num[pos] * p[index].y); pos = binsearch_r(n / 2); if (pos != 0) ans = min(ans, (m - num[pos] + 1) * p[index].y); index++; } memset(a, 0, sizeof(a)); index = n; while (index >= 1) { while (index - 1 >= 1 && p[index].y == p[index - 1].y) { modify(id[p[index].x], 1); index--; } modify(id[p[index].x], 1); if (n - index + 1 < n / 2) {index--; continue;} int pos; pos = binsearch_l(n / 2); if (pos != 0) ans = min(ans, num[pos] * (m - p[index].y + 1)); pos = binsearch_r(n / 2); if (pos != 0) ans = min(ans, (m - num[pos] + 1) * (m - p[index].y + 1)); index--; } if (ans == INF) printf("-1\n"); else printf("%lld\n", ans); } else printf("-1\n"); } return 0;}
- Codeforces Gym 101505D Orchard Division(离散化+树状数组+扫描线+二分)
- CodeForces 652D Nested Segments(树状数组+离散化)
- CodeForces 652D Nested Segments(离散化,树状数组)
- D - Data Mining-Gym 100496D-离线处理+树状数组+离散化
- Codeforces 527D Clique Problem (dp+树状数组+离散化)
- Educational Codeforces Round 10D 离散化+树状数组
- Codeforces 652D Nested Segments 【树状数组 + 离散化】
- codeforces 703D 树状数组 + 离线处理 + 离散化
- 【Codeforces 652 D Nested Segments】+ 树状数组 + 离散化
- Codeforces 652D Nested Segments【离散化+思维+树状数组】
- Nested Segments codeforces 652D 树状数组 +离散化
- CodeForces 652D Nested Segments(树状数组 离散化)
- Nested Segments CodeForces 652D 树状数组+离散化
- CodeForces 629D Babaei and Birthday Cake(树状数组+离散化)
- gym 101505 CTU Open Contest 2016 G Orchard Division
- poj 3109 离散化+扫描线+树状数组
- 离散化 + 线段树(树状数组) + 线扫描法
- HDU 5741 扫描线+离散化+树状数组
- opencv的第一份代码,及其makefile通用格式
- 05-Descriptive/Inferential Statistics Definition
- JVM内存区域模型
- 1005. 继续(3n+1)猜想 (25)
- Java强弱软虚引用概述
- Codeforces Gym 101505D Orchard Division(离散化+树状数组+扫描线+二分)
- 2.3 Linux网络接口
- 百度语音识别Demo -- 简单应用
- Java类加载器的使用
- SQL Server2016使用Day1
- 利用Eclipse Memory Analyzer检查内存泄漏
- java多线程(一)之多线程基础
- 1074. 宇宙无敌加法器(20)
- MySQL Workbench 已停止工作 错误模块名称: KERNELBASE.dll 异常代码: 0xe0434352 程序无法正常启动:( 0xc000007b)