【题解】P2521 [HAOI2011]防线修建(动态凸包)
【题解】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]防线修建(动态凸包)的更多相关文章
- BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )
离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...
- 【bzoj2300】【Luogu P2521】 [HAOI2011]防线修建 动态凸包,平衡树,Set
一句话题意:给你一个凸包,每次可以插入一个点或者询问周长. 动态凸包裸题嘛,用\(Set\)实现.最初每个点坐标做乘三处理,便于取初始三角形的重心作为凸包判定原点. #include <bits ...
- [luogu P2521] [HAOI2011]防线修建
[luogu P2521] [HAOI2011]防线修建 题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国 ...
- P2521 [HAOI2011]防线修建
题目链接:P2521 [HAOI2011]防线修建 题意:给定点集 每次有两种操作: 1. 删除一个点 (除开(0, 0), (n, 0), 与指定首都(x, y)) 2. 询问上凸包长度 至于为什么 ...
- Bzoj2300 / 洛谷P2521 [HAOI2011]防线修建
题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于 ...
- 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)
2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...
- 【BZOJ2300】[HAOI2011]防线修建 set维护凸包
[BZOJ2300][HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可 ...
- bzoj千题计划236:bzoj2300: [HAOI2011]防线修建
http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> ...
- BZOJ [HAOI2011]防线修建(动态凸包)
听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...
随机推荐
- 转载:ubuntu 下的dpkg 的用法
dpkg是一个Debian的一个命令行工具,它可以用来安装.删除.构建和管理Debian的软件包. 下面是它的一些命令解释: 1)安装软件 命令行:dpkg -i <.deb file name ...
- Redis源码解析:09redis数据库实现(键值对操作、键超时功能、键空间通知)
本章对Redis服务器的数据库实现进行介绍,说明Redis数据库相关操作的实现,包括数据库中键值对的添加.删除.查看.更新等操作的实现:客户端切换数据库的实现:键超时相关功能的实现.键空间事件通知等. ...
- vmware中centos、redhat桥接网络配置
第一步 第二步 第三步 centos: redhat:
- 学linux内核与学linux操作系统有什么区别!?
linux内核包括:进程管理,存储管理,IO管理,文件系统等功能.linux操作系统则是linux内核再加上像shell或图形界面和其他的实用软件,比内核庞大的多.建议先学shell命令和linux下 ...
- vue-awesome-swiper轮播插件的使用方法及问题。
在使用vue-awesome-swiper的时候,遇到一些问题,记录一下! 1.npm 安装 npm install vue-awesome-swiper --save 2.使用 在mai ...
- ]ubuntu开机自动挂载的ntfs硬盘的权限问题
原文地址:ubuntu开机自动挂载的ntfs硬盘的权限问题 在linux操作系统中, 挂载是一个非常重要的功能,使用非常频繁. 它指将一个设备(通常是存储设备)挂接到一个已存在的目录上. (这个目录可 ...
- 使用jquery.form.js的ajaxsubmit方法提交数据的Bug
周五同事遇到一个很奇怪的问题,调到下班,虽然问题解决了,但是不知道问题的具体原因,回来翻了翻代码,才发现症结所在,下面就分享出来,供遇到同样问题的同行们参考: 先把问题描述一下,做的功能是使用ajax ...
- 创建JAVASCRIPT对象3种方法
创建JAVASCRIPT对象3种方法 方法一:直接定义并创建对象实例 var obj = new Object(); //创建对象实例 //添加属性obj.num = 5; //添加属性 o ...
- CSS中常用的简写模式
一.font属性简写 font-style:字体样式 normal 默认值.浏览器显示一个标准的字体样式. italic 浏览器会显示一个斜体的字体样式. oblique 浏览器会显示一个倾斜的字体样 ...
- js(一) 三大事件 实现注册验证
ps:小声比比,为什么一周多没更,因为js真的好难啊. 上一周做了一整周的jsp+sevlet+mysql做了一个MVC模式的最基本的新闻系统源码会有空搞出来的 好累 好多的. 三大事件 (鼠标事件. ...