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. I - Caocao's Bridges - hdu 4738(求桥)

    题意:曹操的船之间有一些桥连接,现在周瑜想把这些连接的船分成两部分,不过他只能炸毁一座桥,并且每座桥上有士兵看守,问,他最少需要排多少士兵去炸桥如果不能做到,输出‘-1’ 注意:此题有好几个坑,第一个 ...

  2. 解决hyerv的linux虚拟机网卡地址重启发生变化的问题

    关于linux的虚拟机,当进行虚拟机copy的时候,由于虚拟机配置文件里面会记录网卡的mac地址,所以导致linux里面记录的网卡地址和实际的会有冲突,这样linux会自动把网卡地址提高. 比如原来是 ...

  3. raid5什么意思?怎样做raid5?raid5 几块硬盘?

    一.raid什么意思? RAID是"Redundant Array of Independent Disk"的缩写,raid什么意思了?说白了,中文翻译过来通俗的讲就是磁盘阵列的意 ...

  4. Apache http强制转为https页面访问(转)

    1 在httpd.conf文件里使下面模块生效 LoadModule rewrite_module modules/mod_rewrite.so   2 httpd.conf配置文件或者是在httpd ...

  5. JAVA冒泡排序/JAVA冒泡排序再找出给定数据中的最大值最小值/JAVA数组排序

    //数组中排序    int in[] = {1,6,5,8,9};    Arrays.sort(in);    for(int i=0;i<in.length;i++){       Sys ...

  6. Extjs4学习

    1 Ext js初步 1.1 获取Extjs 下载extjs: 可以从http://extjs.org.cn/ 获得需要的extjs发布包及更多支持. 1.2 搭建学习环境: 假设您的机器已经安装my ...

  7. 第一章:在IDEA里搭建基于Forge的Minecraft mod开发环境

    <基于1.8 Forge的Minecraft mod制作经验分享> 网上关于Forge开发环境搭建的文章其实有不少,但大都是基于Eclipse的. 作为用Java开发的环境,怎么能没有ID ...

  8. Environment Configuration Files

    Environment Configuration Files When a user logs in, an environment is created for that user automat ...

  9. linux配置时间同步

    目标环境,5台linux centos 6.3, 一台作为NTPD服务与外部公共NTP服务同步时间,同时作为内网的NTPD服务器,其他机器与这台服务做时间同步.  服务器IP 角色   说明 同步方式 ...

  10. Freemarker常用技巧(三)

    freemarker模板解析过程 例如:一个freemarker表达式<body> ${hello} </body>,会被解析成三个部分,分别是<body>${he ...