【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]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...
随机推荐
- DataRowState、AcceptChanges、RejectChanges综合使用示例:实现DataGridView数据的增、删、改
下面的示例中,通过一个程序,演示使用DataRowState.AcceptChanges.RejectChanges,实现DataGridView数据的增.删.改. 一.界面设计 二.代码实现 usi ...
- input输入框用el对数字格式化
<input name="doubleInput" type="text" maxlength="32" id="doubl ...
- 关于Cocos2d-x物理引擎用到的类和使用
其实就是这三类PhysicsWorld类,PhysicsBody类,PhysicsShape类. 1.PhysicsWorld类 PhysicsWorld对象代表Cocos2d-x中的物理世界,这个世 ...
- 什么是事务(transaction)?它有什么好处
为了完成对数据的操作,企业应用经常要求并发访问在多个构件之间共享的数据.这些应用在下列条件下应该维护数据的完整性(由应用的商务规则来定义): 分布式访问一个单独的数据资源,以及从一个单独的应用构件访问 ...
- window,centos双系统坏了
在centos中格式化SD卡的时候,操作错误,误将windows系统C盘的给格式化了.C盘是ntf格式的,现在却变为了fat32的格式. 重启系统,发现还是可以进入到centos,但是window进入 ...
- 下面关于XML叙述不正确的是( )
A.XML标记必须关闭 B.XML是大小写敏感的 C.XML文件只能跟DTD文件一块使用 D.XML和XSL结合可以在浏览器上显示 解答:C
- 奇葩问题:ListView中Item与Item中的Button不能单击问题
android中ListView是一个经常要用到的一个组件,用到该组件时经常会碰到ListView的Item和Item中的Button不能单击的问题. 本人在使用时同样也遇到过这样的情况,共有三种情况 ...
- php将汉字转换为拼音和得到词语首字母(三)
<?php function getfirstchar($s0){ $fchar = ord($s0{0}); if($fchar >= ord("A") and $f ...
- [转]oracle存储过程、声明变量、for循环
oracle存储过程.声明变量.for循环 1.创建存储过程 create or replace procedure test(var_name_1 in type,var_name_2 out ty ...
- POJ 3211 Washing Clothes 背包题解
本题是背包问题,可是须要转化成背包的. 由于是两个人洗衣服,那么就是说一个人仅仅须要洗一半就能够了,由于不能两个人同一时候洗一件衣服,所以就成了01背包问题了. 思路: 1 计算洗完同一颜色的衣服须要 ...