BZOJ 2300 防线修建
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 防线修建的更多相关文章
- BZOJ [HAOI2011]防线修建(动态凸包)
听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...
- 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)
2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...
- BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )
离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...
- 防线修建 bzoj 2300
防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还 ...
- bzoj千题计划236:bzoj2300: [HAOI2011]防线修建
http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> ...
- [luogu P2521] [HAOI2011]防线修建
[luogu P2521] [HAOI2011]防线修建 题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国 ...
- P2521 [HAOI2011]防线修建
题目链接:P2521 [HAOI2011]防线修建 题意:给定点集 每次有两种操作: 1. 删除一个点 (除开(0, 0), (n, 0), 与指定首都(x, y)) 2. 询问上凸包长度 至于为什么 ...
- 【BZOJ2300】[HAOI2011]防线修建 set维护凸包
[BZOJ2300][HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可 ...
- 【题解】P2521 [HAOI2011]防线修建(动态凸包)
[题解]P2521 [HAOI2011]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...
随机推荐
- J.Hilburn:高档男装市场颠覆者_网易财经
J.Hilburn:高档男装市场颠覆者_网易财经 J.Hilburn:高档男装市场颠覆者
- iOS图片处理
http://www.cnblogs.com/kenshincui/p/3959951.html
- 提高你的Java代码质量吧:让我们疑惑的字符串拼接方式的选择
一.分析 对于一个字符串进行拼接有三种方法:加号.concat方法.及StringBuiler或StringBuffer. 1."+"方法拼接字符串 str += " ...
- myqltransactionRollbackexception deadlock found when trying to get lock
linux 下远程连接mysq 命令: mysql -h "1.0.0.1" -u username -p 1 获 取锁等待情况 可以通过检查 table_locks_waited ...
- Win7系统安装MySQL5.5.21图解教程
转自:http://www.jb51.net/article/37310.htm 这篇文章主要介绍了如何在win7中安装mysql,所以加上了MySQL的下载过程,希望对需要的人有所帮助 大家都知道M ...
- 矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757
矩阵快速幂是基于普通的快速幂的一种扩展,如果不知道的快速幂的请参见http://www.cnblogs.com/Howe-Young/p/4097277.html.二进制这个东西太神奇了,好多优秀的算 ...
- 开发部署一个简单的Servlet
Servlet是一个执行在服务器端的Java Class文件,载入前必须先将Servlet程序代码编译成.class文件,然后将此class文件放在servlet Engline路径下.Servlet ...
- java中Class.forName与new
一.使用Class.forName 1.装载类 Class clazz = Class.forName("xx.xx.xx"); 2.初始化对象 clazz.newInstance ...
- (转)用eclipse创建一个j2ee的web工程后,左面projects窗口中的项目如何没有显示webRoot文件夹,除了src的文件夹,其他都不显示
左边目录窗口的右上方,有个向下的箭头,点里面的filters,把所有的勾都去掉看看
- redis例子
http://www.cnblogs.com/edisonfeng/p/3571870.html