CF70D(动态凸包)

给出q(<=1e5)个询问,每次在加上一个点,维护凸包,或者询问某个点是否在凸包内(在边上也算)。

听说可以用cdq做……但是并不会。我等蒟蒻只会用平衡树做。

首先,假设已经维护出了某个点按照极角排序的凸包,那么对于加入的一个点,我们首先要查询它是在凸包内还是凸包外(这个功能也可以用于题目中的查询)。O表示极角排序的原点,next表示极角排序的下一个点,pre则表示上一个点:

那么,如果p在凸包外,a\(\times\)b就是正数,若p在凸包内a\(\times\)b则是非正整数。

接着,我们要维护凸包。维护凸包依然要查询next和pre:

类似于gramham,不断通过删除next和pre维护凸包凸性。形象理解一下,可以看成p点伸出了两个筷子,不停尝试夹住凸包(凸包:喵喵喵?)

注意判断点是否在凸包内时,有个小坑点。O点必须选择在凸包内,既不能选择在凸包外也不能选择在凸包的边上。

#include <set>
#include <cmath>
#include <cstdio>
using namespace std; typedef long long LL;
const LL maxn=1e5+5;
double ox=0, oy=0;
struct Point{
LL op, x, y; double angle;
Point (LL a=0, LL b=0):x(a), y(b){}
void getangle(){ angle=atan2(y-oy, x-ox); }
}p[maxn];
Point operator +(const Point &a, const Point &b){ return Point(a.x+b.x, a.y+b.y); }
Point operator -(const Point &a, const Point &b){ return Point(a.x-b.x, a.y-b.y); }
LL operator *(const Point &a, const Point &b){ return a.x*b.y-a.y*b.x; }
bool operator <(const Point &a, const Point &b){ //a是否在b的逆时针处
return a.angle<b.angle; }
LL q;
typedef multiset<Point>::iterator iter;
typedef Point Vector;
multiset<Point> s; iter nxt(iter x){ return x==--s.end()?s.begin():++x; }
iter pre(iter x){ return x==s.begin()?--s.end():--x; } bool in(iter x){
if (s.size()<3) return false;
return (*nxt(x)-*x)*(*pre(x)-*x)<=0; //叉积(是不是神仙操作)
} void add(Point &x){
iter it=s.insert(x);
if (s.size()<=3) return;
if (in(it)){ s.erase(it); return; }
while (s.size()>3&&(*nxt(it)-*it)*(*nxt(nxt(it))-*nxt(it))<=0) //神仙操作*2
s.erase(nxt(it)); //注意加上=0以后,要判断size以免遇到两个点的情况
while (s.size()>3&&(*pre(it)-*it)*(*pre(pre(it))-*pre(it))>=0) //神仙操作*3
s.erase(pre(it));
} bool query(Point &x){
iter it=s.insert(x); bool flag;
if (in(it)) flag=true; else flag=false;
s.erase(it); return flag;
} int main(){
scanf("%lld", &q);
for (LL i=0; i<q; ++i)
scanf("%lld%lld%lld", &p[i].op, &p[i].x, &p[i].y);
Point t=p[0]+p[1]+p[2]; ox=(double)t.x/3; oy=(double)t.y/3;
//这样确定原点,保证原点不在凸包的边上
//若不这样:例子:A(-1, 0) B(1, 0) Q(4, 0)
for (LL i=0; i<q; ++i) p[i].getangle(); //确定极角
for (LL i=0; i<q; ++i){
if (p[i].op==1) add(p[i]);
else puts(query(p[i])?"YES":"NO");
}
return 0;
}

CF70D(动态凸包)的更多相关文章

  1. CF70D Professor's task(动态凸包)

    题面 两种操作: 1 往点集S中添加一个点(x,y); 2 询问(x,y)是否在点集S的凸包中. 数据保证至少有一个2操作, 保证刚开始会给出三个1操作, 且这三个操作中的点不共线. 题解 动态凸包板 ...

  2. 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)

    2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...

  3. BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )

    离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...

  4. [NOI2007]货币兑换Cash(DP+动态凸包)

    第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...

  5. BZOJ [HAOI2011]防线修建(动态凸包)

    听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...

  6. 【BZOJ 1701】Cow School(斜率优化/动态凸包/分治优化)

    原题题解和数据下载 Usaco2007 Jan 题意 小牛参加了n个测试,第i个测试满分是\(p_i\),它的得分是\(t_i\).老师去掉\(t_i/p_i\)最小的d个测试,将剩下的总得分/总满分 ...

  7. Code Chef TSUM2(动态凸包+点分治)

    题面 传送门 题解 真是毒瘤随机化算法居然一分都不给 首先这种树上的题目一般想到的都是点分 我们考虑如何统计经过当前点的路径的贡献,设当前点\(u\)在序列中是第\(c\)个,那么一条路径的贡献就是 ...

  8. codeforces 70 D. Professor's task 动态凸包

    地址:http://codeforces.com/problemset/problem/70/D 题目: D. Professor's task time limit per test 1 secon ...

  9. 【bzoj2300】【Luogu P2521】 [HAOI2011]防线修建 动态凸包,平衡树,Set

    一句话题意:给你一个凸包,每次可以插入一个点或者询问周长. 动态凸包裸题嘛,用\(Set\)实现.最初每个点坐标做乘三处理,便于取初始三角形的重心作为凸包判定原点. #include <bits ...

随机推荐

  1. HZ 和 usleep最小睡眠时间(低精度定时器)

    注:本文论述的情况是内核默认未开启高精度定时器. 不建议这么用,需要较高精度的定时器可参考本博客后面的文章. 一.先上结论 1.默认的HZ是100,usleep的最小时间是10ms: 2.将HZ修改为 ...

  2. struts2获得需要的文件或者访问路径

    在struts2中,上传文件的时候遇到一个很好用但是失效的方法,找到如下替代.并且测试了一下request可以得到的相关路径. 得到request对象: HttpServletRequest requ ...

  3. Springboot监控之一:SpringBoot四大神器之Actuator之3-springBoot的监控和管理--指标说明

    Spring Boot包含很多其他的特性,它们可以帮你监控和管理发布到生产环境的应用.你可以选择使用HTTP端点,JMX或远程shell(SSH或Telnet)来管理和监控应用.审计(Auditing ...

  4. C# EntityFramwork(Model First)使用要点

    本文介绍EntityFramework使用方法 Entity Framework的注意点 由于安装和操作的细节讲起来很琐碎,这部分只罗列出难点,其他细节请自行查阅 安装细节 Pluralize or ...

  5. 第三章 Java内存模型(下)

    锁的内存语义 中所周知,锁可以让临界区互斥执行.这里将介绍锁的另一个同样重要但常常被忽视的功能:锁的内存语义 锁的释放-获取建立的happens-before关系 锁是Java并发编程中最重要的同步机 ...

  6. Shell编程进阶 1.5 if逻辑判断

    逻辑判断 vim if.sh #!/bin/bash ## ## a= ] then echo "a>3" fi sh if.sh a>3 vim if2.sh #!/ ...

  7. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...

  8. eclipse DDMS导出文件失败--android Failed to push the item

    我们在写安卓程序的时候,经常会用Eclipse导出模拟器的文件管理里面的文件,但有时候会报错,导致无法导出文件. 报错信息 Failed to push selection: Local path d ...

  9. Eclipse 快键键(持续更新)

    本人抛弃一些简单常见的快键键,例如 ctrl+c   ,+v ,+z之类的 1.ctrl+d 删除一整行 2.ctrl+f 搜索 3.光标选中几行,ctrl+alt+↓ 向下复制选中的那几行 4.光标 ...

  10. LaTeX数学公式基础

    LaTeX数学公式 参考:https://www.cnblogs.com/Sinte-Beuve/p/6160905.html 原博客显示有点问题,重新搬运整理LaTeX数学公式部分的基本用法 基础 ...