题目链接:http://codeforces.com/contest/70/problem/D

Once a walrus professor Plato asked his programming students to perform the following practical task.

The students had to implement such a data structure that would support a convex hull on some set of points S. The input to the program had q queries of two types:

1. Add a point with coordinates (x, y) into the set S. Note that in this case the convex hull of S could have changed, and could have remained the same.

2. Say whether a point with coordinates (x, y) belongs to an area limited by the convex hull, including the border.

All the students coped with the task. What about you?

Input

The first line contains an integer q (4 ≤ q ≤ 105).

Then follow q lines in the following way: "t x y", where t is the query type (1 or 2), and (x, y) are the coordinates of the point ( - 106 ≤ x, y ≤ 106, x and y are integers).

There is at least one query of type 2.

It is guaranteed that the three queries of the first type follow first and the points given in the queries form a non-degenerative triangle. Also all the points added in S are distinct.

Output

For each query of the second type print one string containing "YES", if the point lies inside the convex hull or on its border. Otherwise, print "NO".

题目大意:q个操作。操作1:往点集中添加一个点。操作2:给一个点,问这个点是否在点集所构成的凸包内部(包括边缘)。

思路:增量法求动态凸包。可以看:http://blog.csdn.net/crazy_ac/article/details/8499443

PS:原来map的迭代器是首尾相连的……

代码(156MS):

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
typedef map<int, int> MPII; struct Point {
int x, y;
Point() {}
Point(int x, int y): x(x), y(y) {}
Point(MPII::iterator it): x(it->first), y(it->second) {}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
}; LL cross(const Point &a, const Point &b) {
return (LL)a.x * b.y - (LL)a.y * b.x;
} LL cross(const Point &o, const Point &a, const Point &b) {
return cross(a - o, b - o);
} bool below(MPII &mp, Point p) {
if(mp.empty()) return false;
if(p.x < mp.begin()->first || mp.rbegin()->first < p.x) return false;
MPII::iterator a = mp.lower_bound(p.x), b = a--;
if(b->first == p.x) return b->second >= p.y;
return cross(a, b, p) <= ;
} void insert(MPII &mp, Point p) {
if(below(mp, p)) return ;
MPII::iterator a, b, it;
mp[p.x] = p.y;
it = mp.lower_bound(p.x); b = it; ++b;
if(b != mp.end()) {
a = b++;
while(b != mp.end() && cross(p, a, b) >= )
mp.erase(a), a = b++;
} a = it; --a;
if(it != mp.begin() && a != mp.begin()) {
b = a--;
while(b != mp.begin() && cross(p, b, a) <= )
mp.erase(b), b = a--;
}
} MPII up, down;
int q, op, x, y; int main() {
scanf("%d", &q);
while(q--) {
scanf("%d%d%d", &op, &x, &y);
if(op == ) {
insert(up, Point(x, y));
insert(down, Point(x, -y));
} else {
puts((below(up, Point(x, y)) && below(down, Point(x, -y))) ? "YES" : "NO");
}
}
}

最新文章

  1. 考勤系统代码分析——主页布局easyui框架
  2. ionic tab导航在android 真机测试中 导航在顶部解决办法
  3. 电脑无法登陆ftp
  4. zepto源码--extend--学习笔记
  5. C++智能指针管理类
  6. javaSE第十五天
  7. Nginx简单性能调优
  8. Cordova+angularjs+ionic+vs2015开发(五)
  9. AWS s3 python sdk code examples
  10. Android App优化建议(转载)
  11. BZOJ 2006 NOI2010 超级钢琴 划分树+堆
  12. 组态Log4j(非常具体的)
  13. xp安装maven
  14. 【C语言】浅谈可变参数与printf函数
  15. 【Java学习笔记之十八】Javadoc注释的用法
  16. Reactor模式的.net版本简单实现--DEMO
  17. [Swift]LeetCode918. 环形子数组的最大和 | Maximum Sum Circular Subarray
  18. MySQL_参数设置
  19. linux --nginx篇
  20. socket shutdown和close的区别

热门文章

  1. ubuntu 64bit arm-linux-gcc: No such file or directory 解决
  2. 例题.点击按钮显示内容+弹窗效果+ajax
  3. 蓝牙BLE MTU规则与约定
  4. CDH介绍
  5. php--memcahce安装
  6. php--group_concat()函数总结
  7. Windows创建文件链接
  8. node express 学习1
  9. Spark Programming--Transformations
  10. 在css中定义滚动条样式