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]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足 ...
随机推荐
- struct 结构
//原始套接字学习笔记之代码结构 /* *host端程序结构 */ #include <> #define .. //主函数 int main() { //建立发送线程 pthread_t ...
- AFNetworking (3.1.0) 源码解析 <三>
今天要介绍的是Reachability文件夹下的AFNetworkReachabilityManager类.通过字面意思我们就可以知道AFNetworkReachabilityManager是用来监测 ...
- 遍历INI文件和删除指定域内容
主要还是使用的INI文件操作的API,只是把参数修改下. BOOL WINAPI WritePrivateProfileString( __in LPCTSTR lpAppName, __in LPC ...
- 4 Java学习之 反射Reflection
1. 反射概念 反射机制就是:动态地获取类的一切信息,并利用这些信息做一些你想做的事情. java反射机制能够知道类名而不实例化对象的状态下,获得对象的属性或调用方法. JAVA反射机制是在运行状态 ...
- 初学者学Java(十五)
再谈数组 在这一篇中我们来讲一下关于数组的排序和查找的方法. 排序 说到数组的排序,就不得不说冒泡这种经典的方法. 1.冒泡排序 冒泡排序的基本思想是比较两个相邻元素的值,如果满足条件就交换元素的值( ...
- 获取Android自己写好了的apk以及反编译
今天,我们先说一下,获取Android自带的apk以及反编译它们来学习Android工程师是怎样写的,今天我们就以拿到Android自带的短信管理器的apk为例子 你可能有疑问,为什么要那么麻烦,从系 ...
- ViewPager 详解(四)----自主实现滑动指示条
前言:前面我们用了三篇的时间讲述了有关ViewPager的基础知识,到这篇就要进入点实际的了.在第三篇<ViewPager 详解(三)---PagerTabStrip与PagerTitleStr ...
- 海尔的U+智慧生活操作系统
通过一个手机APP就能操控家庭内的不同品牌的家电家居设备.在连接Wifi的状态下,海尔智能路由器能够自动连接上家庭里的智能冰箱.智能洗衣机.智能空调.智能烤箱.空气盒子等设备端.在智能手机上下载海尔U ...
- js截取字符串区分汉字字母代码
js截取字符串并且区分汉字字母,一个汉字辨别为两个字节. function substr(str, len) { if (!str || !len) { return ''; } // 预期计数:中文 ...
- Android AIDL图解
代码来自:http://www.cnblogs.com/mandroid/archive/2011/02/26/1965428.html (XXX.AIDL自动生成的IXXX.java类中 ...