博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2300 防线修建
阅读量:6196 次
发布时间:2019-06-21

本文共 2397 字,大约阅读时间需要 7 分钟。

http://www.lydsy.com/JudgeOnline/problem.php?id=2300

题意:给点,有以下操作:删去一个点,询问这些点构成凸包的周长。

思路:用splay维护上凸壳,splay排序的关键字是X,同时还要记录每个点与左右点的斜率,当加入一个点时,我们找到它应该在的X的位置,一个个减掉左边,一个个减掉右边,符合条件就是当左边的斜率大于右边的斜率,就表明它在凸包上。

PS:如果当前加入点的左边斜率小于右边斜率,说明它在凸包内,可以直接删掉这个点。

#include
#include
#include
#include
#include
struct node{ int id,val,opt;}q[200005];struct point{ double x,y;}p[200005];const double eps=1e-9;int tmp,root;double c[200005],xx[200005],yy[200005],ans,rk[200005],lk[200005];int n,ch[200005][2],fa[200005],vis[200005];int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f;}void rotate(int x,int &rt){ int y=fa[x],z=fa[y],l,r; if (ch[y][0]==x) l=0;else l=1;r=l^1; if (y!=rt){ if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=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][0]==y^ch[y][0]==x) rotate(x,rt); else rotate(y,rt); } rotate(x,rt); }}void find(int k,double X){ if (!k) return; if (xx[k]
=lk[id]){getslope(x,y);fa[id]=0;ch[y][0]=0;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][0]); ans-=dis(x,id); ans-=dis(x,y); ans+=dis(y,id); fa[x]=ch[x][0]=ch[x][1]=0; ch[id][0]=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][1]); ans-=dis(x,id); ans-=dis(x,y); ans+=dis(y,id); fa[x]=ch[x][1]=ch[x][0]=0; ch[id][1]=y;fa[y]=id; getslope(id,y); x=y; }}int main(){ int m=read(),x=read(),y=read(); n=read(); for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); int T=read(); for (int i=1;i<=T;i++){ q[i].opt=read(); if (q[i].opt==2) continue; q[i].id=i;q[i].val=read();vis[q[i].val]=1; } insert(0,0,1); insert(m,0,2); insert(x,y,3); for (int i=1;i<=n;i++) if (!vis[i]){ insert(p[i].x,p[i].y,i+3); } int top=0; for (int i=T;i>=1;i--){ if (q[i].opt==2){ c[++top]=ans; }else{ insert(p[q[i].val].x,p[q[i].val].y,q[i].val+3); } } for (int i=top;i>=1;i--) printf("%.2f\n",c[i]);}

 

转载于:https://www.cnblogs.com/qzqzgfy/p/5671055.html

你可能感兴趣的文章
前端代码标准最佳实践:HTML篇
查看>>
优易联 -- 项目拨付款管理系统
查看>>
技术改变生活——电影目录核对工具(php)
查看>>
Sed one line
查看>>
OpenInventor笔记:线性坐标轴PoLinearAxis的使用
查看>>
[转]ORACLE函数大全
查看>>
Unsupported compiler 'GCC 4.2' selected for architecture 'i386'
查看>>
修改Xcode配置并支持iPhone上dylib工程 实例
查看>>
iphone-命令行编译--xcodebuild
查看>>
java keytool证书工具使用小结
查看>>
全新的PDO数据库操作类(仅适用Mysql)
查看>>
ImportError: No module named setuptools 解决方案
查看>>
Microsoft Team Foundation Server 2010 安装 序列号 注册码
查看>>
转 OFBiz安全组
查看>>
WMI服务故障,VBS脚本无法运行错误
查看>>
常见充值方式介绍及对比
查看>>
2012最新75款好看的英文字体免费下载【中篇】
查看>>
SilverLight学习笔记--进一步学习Isolated Storage独立存储一(理论篇)
查看>>
Google Cloud Messaging for Android (GCM)已推出,将取代C2DM框架
查看>>
敏捷结果30天之第十二天:效率角色-你是启动者还是完成者
查看>>