http://www.lydsy.com/JudgeOnline/problem.php?id=2300

题意:给点,有以下操作:删去一个点,询问这些点构成凸包的周长。

思路:用splay维护上凸壳,splay排序的关键字是X,同时还要记录每个点与左右点的斜率,当加入一个点时,我们找到它应该在的X的位置,一个个减掉左边,一个个减掉右边,符合条件就是当左边的斜率大于右边的斜率,就表明它在凸包上。

PS:如果当前加入点的左边斜率小于右边斜率,说明它在凸包内,可以直接删掉这个点。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
struct node{
int id,val,opt;
}q[];
struct point{
double x,y;
}p[];
const double eps=1e-;
int tmp,root;
double c[],xx[],yy[],ans,rk[],lk[];
int n,ch[][],fa[],vis[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void rotate(int x,int &rt){
int y=fa[x],z=fa[y],l,r;
if (ch[y][]==x) l=;else l=;r=l^;
if (y!=rt){
if (ch[z][]==y) ch[z][]=x;else ch[z][]=x;
}else rt=x;
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
}
void splay(int x,int &rt){
while (x!=rt){
int y=fa[x],z=fa[y];
if (y!=rt){
if (ch[z][]==y^ch[y][]==x) rotate(x,rt);
else rotate(y,rt);
}
rotate(x,rt);
}
}
void find(int k,double X){
if (!k) return;
if (xx[k]<X+eps) tmp=k,find(ch[k][],X);
else find(ch[k][],X);
}
int suc(int x){
x=ch[x][];
while (ch[x][]) x=ch[x][];
return x;
}
int pre(int x){
x=ch[x][];
while (ch[x][]) x=ch[x][];
return x;
}
double sqr(double x){
return x*x;
}
double dis(int x,int y){
if (!x||!y) return 0.0;
return sqrt(sqr(xx[x]-xx[y])+sqr(yy[x]-yy[y]));
}
void getslope(int x,int y){
if (!x){lk[y]=1e9;return;}
if (!y){rk[x]=-1e9;return;}
if (fabs(xx[x]-xx[y])<1e-){
if (yy[x]<yy[y]) rk[x]=lk[y]=1e9;
else rk[x]=lk[y]=-1e9;
return;
}
rk[x]=lk[y]=(yy[x]-yy[y])/(xx[x]-xx[y]);
}
void insert(double X,double Y,int id){
tmp=;
find(root,X);int x=tmp,y=;
if (!x){
x=root;
while (ch[x][]) x=ch[x][];
splay(x,root);
y=x;x=;
}else splay(x,root),splay(y=suc(x),ch[x][]);
xx[id]=X;yy[id]=Y;
if (y) fa[id]=y,ch[y][]=id;
else fa[id]=x,ch[x][]=id;
getslope(x,id);getslope(id,y);
ans-=dis(x,y);
if (rk[id]>=lk[id]){getslope(x,y);fa[id]=;ch[y][]=;ans+=dis(x,y);return;}
splay(id,root);
root=id;
x=pre(id);
ans+=dis(x,id);
while (lk[x]<=rk[x]&&x){
y=pre(x);
splay(y,ch[x][]);
ans-=dis(x,id);
ans-=dis(x,y);
ans+=dis(y,id);
fa[x]=ch[x][]=ch[x][]=;
ch[id][]=y;fa[y]=id;
getslope(y,id);
x=y;
}
x=suc(id);
ans+=dis(x,id);
while (lk[x]<=rk[x]&&x){
y=suc(x);
splay(y,ch[x][]);
ans-=dis(x,id);
ans-=dis(x,y);
ans+=dis(y,id);
fa[x]=ch[x][]=ch[x][]=;
ch[id][]=y;fa[y]=id;
getslope(id,y);
x=y;
}
}
int main(){
int m=read(),x=read(),y=read();
n=read();
for (int i=;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
int T=read();
for (int i=;i<=T;i++){
q[i].opt=read();
if (q[i].opt==) continue;
q[i].id=i;q[i].val=read();vis[q[i].val]=;
}
insert(,,);
insert(m,,);
insert(x,y,);
for (int i=;i<=n;i++)
if (!vis[i]){
insert(p[i].x,p[i].y,i+);
}
int top=;
for (int i=T;i>=;i--){
if (q[i].opt==){
c[++top]=ans;
}else{
insert(p[q[i].val].x,p[q[i].val].y,q[i].val+);
}
}
for (int i=top;i>=;i--)
printf("%.2f\n",c[i]);
}

BZOJ 2300 防线修建的更多相关文章

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

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

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

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

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

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

  4. 防线修建 bzoj 2300

    防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还 ...

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

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

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

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

  7. P2521 [HAOI2011]防线修建

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

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

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

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

    [题解]P2521 [HAOI2011]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...

随机推荐

  1. KVM几种缓存模式

    原文在这里: http://pic.dhe.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=%2Fliaat%2Fliaatbpkvmguestca ...

  2. Struts2学习笔记(一):Struts2开发环境的配置

    一.Struts2应用所需的jar文件. 开发struts2应用需要依赖的jar文件在解压目录下的lib文件夹里面.开发struts2程序最少需要的jar文件为:struts2-core-2.xx.j ...

  3. cocos2d-x CCAction:动作(转)

    透明度变化的功能挺不错.   瞬时动作 瞬时动作不需要时间,立即完成 [cpp]   //放置,=setPosition()   pRole->runAction(CCPlace::create ...

  4. 计算方法(三)C#矩阵类库

    测量平差以及工科中常常用到矩阵的相关运算,因此自己写了一个,同时考虑到了类库的可用性,这次又重载了比较匀运算符,修正了一些问题 using System; using System.Collectio ...

  5. mongodb地理空间计算逻辑

    "1/地球半径"是怎么得出的 参考文档如下: http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates http:// ...

  6. 执行start-dfs.sh后,datenode没有启动

    Hadoop2.2.0启动异常 – Incompatible clusterIDs 2014年08月29日 ⁄ 综合 ⁄ 共 2399字 ⁄ 字号 小 中 大 ⁄ 评论关闭 今天启动Hadoop2.2 ...

  7. iOS UI_APPEARANCE_SELECTOR

    iOS后属性带UI_APPEARANCE_SELECTOR 可以统一设置全局作用 例如: 1>开关控件 @property(nullable, nonatomic, strong) UIColo ...

  8. 批处理备份和恢复mysql数据库

    备份 set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%" md "D: ...

  9. swing菜单,常用组件,常用容器

    1菜单 import javax.swing.*; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event ...

  10. Integer和int的详细比较(转)

    Integer与int的区别我们耳熟详的有两点:1.Integer是int的包装类.2.Integer的默认初始值是null,而int的默认初试值是0. 下面通过代码进行详细比较. public cl ...