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. java排序算法-选择排序

    public class SelectionSort { private static void selectSortTest() { int[] sortArray = { 5, 2, 4, 1, ...

  2. windows 编程—— 头文件 指引

    定义    相关头文件 #define UNICODE  <WINUSER.h> <WINNT.h>  <WINBASE.h> #define _UNICODE   ...

  3. 一般处理程序中使用Session出现未将对象引用设置到对象的实例

    遇到问题:未将对象引用设置到对象的实例 那就在你的一般处理程序中加入红色背景的代码吧 using System; using System.Collections.Generic; using Sys ...

  4. Android ArrayAdapter MultiAutoCompleteTextView

    MultiAutoCompleteTextView 继承自AutoCompleteTextView,它和AutoCompleteTextView不同的就是能处理多个输入字段,如发送短信界面的联系人列表 ...

  5. 错误处理:java.lang.NoClassDefFoundError: org/apache/taglibs/standard/tag/rt/core/ForEachTag

    在使用JSP.Servlet进行开发时,遇到java.lang.NoClassDefFoundError: org/apache/taglibs/standard/tag/rt/core/ForEac ...

  6. Android文档资源大放送 感兴趣的话可以网盘下载(个人收集)

    Google.Android.SDK开发范例大全.第3版源码.rar http://pan.baidu.com/s/1c0epYzm 精通Android 3中文版(Pro Android 3).pdf ...

  7. asp.net微信开发第八篇----永久素材管理

    除了3天就会失效的临时素材外,开发者有时需要永久保存一些素材,届时就可以通过本接口新增永久素材. 最近更新,永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用 ...

  8. 请帮我看看这个页面,红色部份如何改才能保存到ACCess数据库中

    <% if session("shiwei_username")="" then %> <script language="java ...

  9. HTML5与APP的交互

    phonegap框架,html5直接用于移动开发的框架.现版本UI延迟据说还是略大. App中搞活动,每次都通过mobile api把url给app即可. App操作Html webview.load ...

  10. ImageView设置点击效果没有用?ImageView src的图片大小改变不了?

    ImageView设置点击效果没有用? 解决 1.ImageView xml里面必须clickable 和longClickable为true <ImageView android:layout ...