【题解】P2521 [HAOI2011]防线修建(动态凸包)

凸包是易插入不好删除的东西,按照剧情所以我们时光倒流

然后问题就是维护凸包的周长,支持加入

本来很简单,但是计算几何就是一些小地方经验不足容易WA和RE

然后代码注释里有一些经验

//@winlere
#include<iostream>
#include<set>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define pf(x) ((x)*(x))
#define DEBUG(s,a) cerr<<#s" = "<<(s)<<" \n"[(a)==1]
#define getchar() (__c==__ed?(__ed=__buf+fread(__c=__buf,1,1<<18,stdin),*__c++):*__c++) using namespace std; typedef long long ll; char __buf[1<<18],*__c=__buf,*__ed=__buf;
inline int qr(){
int ret=0,f=0,c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
} const int maxn=1e5+5;
struct NODE{//向量 坐标用一个结构体代替就行了
ll x,y;//用ll吧 别小气
NODE operator - (NODE b)const{return {x-b.x,y-b.y};}
ll operator % (NODE b)const{return x*b.y-y*b.x;}
bool operator < (NODE b)const{return x<b.x;}
double operator ^ (NODE b)const{return sqrt(pf(x-b.x)+pf(y-b.y));}
}data[maxn],capt;
vector< pair<int,int> > ve;
double len,ans[maxn];
bool in[maxn];
set<NODE> s; void insert(NODE x){
vector<NODE> ve;
if((*s.upper_bound(x)-x)%(x-*--s.upper_bound(x))<0) return;//先判断是否能够插入,这样以后好写一些
for(set<NODE>::iterator t=--s.upper_bound(x),temp;t!=s.begin();t=temp){
temp=prev(t);
if((x-*temp)%(*t-*temp)<0) ve.push_back(*t);//避免一边用iterator一边erase
else break;
}
reverse(ve.begin(),ve.end());
for(set<NODE>::iterator t=s.upper_bound(x),temp;t!=--s.end();t=temp){
temp=next(t);
if((*temp-x)%(*temp-*t)>0) ve.push_back(*t);//同上
else break;
}
if(ve.size()==0)//多写几个if比仔细比巧妙统一快得多,对于=0,=1都特判一下,这里只要=0特判
len+=(*s.upper_bound(x)^x)+(*--s.upper_bound(x)^x)-(*--s.upper_bound(x)^*s.upper_bound(x));
else {
auto l=*--s.find(ve.front()),r=*++s.find(ve.back());
len+=(l^x)+(r^x)-(l^ve.front())-(r^ve.back());
for(int t=1,ed=ve.size();t<ed;++t) len-=ve[t]^ve[t-1];//多写一个循环没问题
for(auto t:ve) s.erase(t);
}
s.insert(x);
} int n,m,x,y,q;
int main(){
n=qr(); capt.x=qr(),capt.y=qr(); m=qr();
s.insert(capt); s.insert({n,0}); s.insert({0,0}); len=(capt^*s.begin())+(capt^*s.rbegin());
for(int t=1;t<=m;++t) data[t].x=qr(),data[t].y=qr();
q=qr();
for(int t=1;t<=q;++t){
int op=qr();
ve.push_back(op==1?(pair<int,int>){op,qr()}:(pair<int,int>){op,t});
if(op==1) in[ve.back().second]=1;
}
for(int t=1;t<=m;++t)
if(!in[t])
insert(data[t]);
reverse(ve.begin(),ve.end());
for(auto t:ve)
if(t.first==1) insert(data[t.second]);
else ans[t.second]=len;
reverse(ve.begin(),ve.end());
for(auto t:ve)
if(t.first==2) printf("%.2lf\n",ans[t.second]);
return 0;
}

【题解】P2521 [HAOI2011]防线修建(动态凸包)的更多相关文章

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

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

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

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

  3. [luogu P2521] [HAOI2011]防线修建

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

  4. P2521 [HAOI2011]防线修建

    题目链接:P2521 [HAOI2011]防线修建 题意:给定点集 每次有两种操作: 1. 删除一个点 (除开(0, 0), (n, 0), 与指定首都(x, y)) 2. 询问上凸包长度 至于为什么 ...

  5. Bzoj2300 / 洛谷P2521 [HAOI2011]防线修建

    题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于 ...

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

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

  7. 【BZOJ2300】[HAOI2011]防线修建 set维护凸包

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

  8. bzoj千题计划236:bzoj2300: [HAOI2011]防线修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> ...

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

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

随机推荐

  1. 【[Offer收割]编程练习赛9 B】水陆距离

    [题目链接]:http://hihocoder.com/problemset/problem/1478 [题意] [题解] 一开始把所有的水域的位置都加入到队列中去; 然后跑一个bfs. 第一次到达的 ...

  2. Centos7 Apache配置虚拟主机的三种方式

    https://blog.csdn.net/tladagio/article/details/80760261 一.虚机主机的三种方式 1.基于IP 2.基于IP+端口 3.基于域名 官网文档:htt ...

  3. 关于Java语言for循环内外变量定义的问题

    今天看书时,看到一个代码,一个在循环外面没有用的变量,后即有了我的问题,在后面: 我的问题: 变量循环内定义,例如:while(true){String splitStr = null;}这“些”个s ...

  4. Fiddler快速入门

    Fiddler是一个免费.强大.跨平台的HTTP抓包工具.Wireshark也是一个强大的抓包工具,不过Wireshark是一个通用的抓包工具,主要精力放在各种协议上了,针对HTTP的特定功能较少.所 ...

  5. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

  6. js创建对象的三种方式和js工厂模式创建对象

    文章地址: https://www.cnblogs.com/sandraryan/ 创建对象 创建对象的三种方式 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象 1. 调用系统的构造函数 ...

  7. Fragment开发实战(一)

    一. Fragment的特征: 1. Fragment总是Activity界面的组成部分.Fragment可调用getActivity()方法获取它所在的Activity,Activity可调用Fra ...

  8. PHP 面试题 一

    1.用PHP打印出前一天的时间格式是2017-5-10 22:21:21(2分) 月,日没有前导零:2017-5-1 22:21:21echo date("Y-n-j H:i:s" ...

  9. springboot2.0.2+redis+spring-session 解决session共享的问题

    准备工作 新建两个springboot2.0.2版本的服务,配置文件添加: #在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为 eurek ...

  10. js基础——流程控制语句

    1.if语句 if(条件表达式){    若条件成立只执行我,下面的分支不执行   }else if(条件表达式){   语句;  }else if(条件表达式){   语句;  }else{     ...