【BZOJ2300】[HAOI2011]防线修建 set维护凸包
【BZOJ2300】[HAOI2011]防线修建
Description
上图中,A,B,C,D,E点为A国城市,且目前都要保护,那么修建的防线就会是A-B-C-D,花费也就是线段AB的长度+线段BC的长度+线段CD的长度,如果,这个时候撤销B点的保护,那么防线变成下图
Input
Output
对于每个询问输出1行,一个实数v,表示修建防线的花费,保留两位小数
Sample Input
2
1 2
3 2
5
2
1 1
2
1 2
2
Sample Output
5.84
4.47
HINT
题解:容易想到离线,然后本题就变成了加点和维护凸包,可以用平衡树来维护凸包来搞(以前一直以为必须用Splay,结果发现好像set就行)。
具体地,我们在set中的点是按x值从小到大排序的。在加入一个点时,先找到凸包中它的前驱和后继节点,用叉积判一下当前点是否已经在凸包里面。如果在则不用加点,否则加入当前点,并不断执行以下操作:
如果当前点和左侧两个点形成的不是上凸包,则将当前点的前驱删掉,否则退出。
右面同理。
然后就做完了,细节也不是特别多。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
#include <cmath>
using namespace std;
const int maxn=200010;
struct point
{
int x,y;
point() {}
point(int a,int b) {x=a,y=b;}
bool operator != (const point &a) const {return (x!=a.x)||(y!=a.y);}
bool operator < (const point &a) const {return (x==a.x)?(y<a.y):(x<a.x);}
point operator - (const point &a) const {return point (x-a.x,y-a.y);}
int operator * (const point &a) const {return x*a.y-y*a.x;}
}p[maxn];
double dis(const point &a,const point &b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
set<point> s;
set<point>::iterator it;
double ans;
int n,m,q;
int del[maxn],op[maxn],qi[maxn];
double qa[maxn];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void add(point x)
{
point a,b,c;
it=s.upper_bound(x),b=*it,it--,a=*it;
if(x.x==b.x) return ;
if((x-a)*(b-x)>=0) return ;
ans-=dis(a,b);
while(a!=point(0,0))
{
it--,c=*it;
if((a-c)*(x-a)>=0) ans-=dis(a,c),s.erase(s.find(a)),a=c;
else break;
}
it=s.find(b);
while(b!=point(n,0))
{
it++,c=*it;
if((b-x)*(c-b)>=0) ans-=dis(b,c),s.erase(s.find(b)),b=c;
else break;
}
ans+=dis(a,x)+dis(x,b);
s.insert(x);
}
int main()
{
int i,a,b;
n=rd(),a=rd(),b=rd(),m=rd();
s.insert(point(0,0)),s.insert(point(n,0)),s.insert(point(a,b));
ans=dis(point(0,0),point(a,b))+dis(point(n,0),point(a,b));
for(i=1;i<=m;i++) p[i].x=rd(),p[i].y=rd();
q=rd();
for(i=1;i<=q;i++)
{
op[i]=rd();
if(op[i]==1) qi[i]=rd(),del[qi[i]]=1;
}
for(i=1;i<=m;i++) if(!del[i]) add(p[i]);
for(i=q;i>=1;i--)
{
if(op[i]==2) qa[i]=ans;
else add(p[qi[i]]);
}
for(i=1;i<=q;i++) if(op[i]==2) printf("%.2lf\n",qa[i]);
return 0;
}
【BZOJ2300】[HAOI2011]防线修建 set维护凸包的更多相关文章
- 2019.02.21 bzoj2300: [HAOI2011]防线修建(set+凸包)
传送门 题意:动态维护凸包周长. 思路: 见这篇求面积的吧反正都是一个套路. 代码: #include<bits/stdc++.h> #define int long long #defi ...
- [日常摸鱼]Luogu2521[HAOI2011]防线修建-set维护凸包
https://www.luogu.org/problemnew/show/2521 题意:维护一个上凸包:删点,查询周长 很容易想到把问题转换为离线:先读入全部操作,记录下最后剩下的点,倒着加点来维 ...
- 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)
2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...
- bzoj千题计划236:bzoj2300: [HAOI2011]防线修建
http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> ...
- BZOJ2300[HAOI2011]防线修建——非旋转treap+凸包(平衡树动态维护凸包)
题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于 ...
- BZOJ [HAOI2011]防线修建(动态凸包)
听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...
- BZOJ2300: [HAOI2011]防线修建
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2300 (我只是在发以前写过的题.. 因为题目没说强制在线,所以离线乱搞就可以了.先把点删掉然后 ...
- BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )
离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...
- 【题解】P2521 [HAOI2011]防线修建(动态凸包)
[题解]P2521 [HAOI2011]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...
随机推荐
- Windoows窗口程序五
程序执行机制 过程驱动-程序的执行过程是按照预订好的顺序执行. 事件驱动-程序的执行是无序,用户可以根据需要随机触发相应的事件. Win32窗口程序就是采用事件驱动方式执行,也就是消息机制. 当系统通 ...
- C#多播委托/多播代理
定义:委托是一种在对象里保存方法引用的类型,同时也是一种类型安全的函数指针.理解委托的一种方式可以把委托的作用当作是给方法签名指定名称.委托的定义类似于方法的定义,但没有方法体,定义的委托名前要加上关 ...
- linux -- ubuntu 14.10开机出现错误“Error found when loading /root/.profile”解决
修改完root权限自动登录后,发现开机出现以下提示: Error found when loading /root/.profile stdin:is not a tty ………… 解决方法:在终端中 ...
- CentOS 7修改MySQL 5.6字符集为UTF-8
MySQL编码原因会导致数据库出现中文乱码 解决办法: 修改MySQL数据库字符编码为UTF-8,UTF-8包含全世界所有国家需要用到的字符,是国际编码. 具体操作: 1.进入MySQL控制台 mys ...
- par函数的new 参数-进行图片的叠加
默认调用高级绘图函数的时候,会另外在绘制一副图,为了将两幅图绘制在同一张纸上,可以设置new = TRUE 代码示例: plot(1:5, c(2,3,2,3,2), col = "red& ...
- samtools flags 的含义
对于双端比对的数据,生成的BAM文件中,R1端序列和R2端序列的标识符是一样的,之前一直不知道如何根据bam文件区分哪条序列是R1端,哪条序列是R2端,昨天仔细研究了一下,原来代表R1端和R2端的信息 ...
- PHP必备知识:如何下载样式文件中的图片
<?php header("content-type:text/html;charset=utf-8"); set_time_limit(0); $styleImg = fi ...
- 接口日志记录AOP实现-LogAspect
使用spring aop日志记录 所需jar包 pom.xml <!-- logger begin --> <dependency> <groupId>org.sl ...
- CSS3 transform 引起z-index失效
https://my.oschina.net/u/2941696/blog/1529373
- Android NDK开发-2-环境搭建
1.环境变量配置NDK 2.选中项目,右键属性菜单,创建一个新的编译器