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]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...
随机推荐
- K - Treasure Exploration - POJ 2594(最小路径覆盖+闭包传递)
题意:给一个有向无环图,求出来最小路径覆盖,注意一个点可能会被多条路径重复 分析:因为有可能多条路径走一个点,可又能会造成匹配的不完全,所以先进行一次闭包传递(floyd),然后再用二分匹配的方法求出 ...
- Java的多线程(上)
多线程的优点和必要性是不言而喻的. 三种方法实现多线程 1. 继承Thread class A extends Thread{ public void run() {...} } 使用时, new A ...
- HTTP学习笔记5-常用报头
24,在普通报头中,有少数报头域应用域所有的请求和响应消息,但并不用于被传输的实体,这些报头域只用于传输的消息. 25,常用的普通报头Cache-Control: Cache-Control普通报头域 ...
- Ubuntu Server安全Webserver搭建流程
之前整过CentOS.整了Ubuntu才发现,Ubuntu简单多了--不知道性能相比又怎样. 以Ubtuntu 14.04为例.记录一下搭建流程. 一.SSHserver 第一件事当然是ssh,默认安 ...
- 《火球——UML大战需求分析》(第1章 大话UML)——1.4 如何学好UML?
说明: <火球——UML大战需求分析>是我撰写的一本关于需求分析及UML方面的书,我将会在CSDN上为大家分享前面几章的内容,总字数在几万以上,图片有数十张.欢迎你按文章的序号顺序阅读,谢 ...
- android 接听和挂断实现方式
参考:android 来电接听和挂断 支持目前所有版本 注意:android2.3版本及以上不支持下面的自动接听方法. (会抛异常:java.lang.SecurityException: Neith ...
- Linux shell入门基础(二)
二.shell对文本的操作 01.查看文本的命令 #cat /etc/passwd(并非对文本文件操作) #tail -5 /etc/passwd(查看末尾5行) #tail -f /var/log/ ...
- select 响应时间 js
HTML form select表单标签案例代码如下: 跳转菜单的需要放在head头部标签内的JS脚本代码:<script type="text/javascript"> ...
- ServletContextListener 解析用法
ServletContext 被 Servlet 程序用来与 Web 容器通信.例如写日志,转发请求.每一个 Web 应用程序含有一个Context,被Web应用内的各个程序共享.因为Context可 ...
- Hadoop参数优化
dfs.block.size 决定HDFS文件block数量的多少(文件个数),它会间接的影响Job Tracker的调度和内存的占用(更影响内存的使用), mapred.map.tasks.spec ...