题解:P2521 [HAOI2011] 防线修建
题意
给定若干个点,实现下列操作:
- 删除一个点。
- 查询上凸包的周长。
分析
建议先完成【模板】二维凸包。
对于这个删除操作,我们没有好的方法去在线维护它。
考虑离线询问。
这样删除操作就变成了插入操作。
插入一个新点有如下两种情况:
- 新点在凸包内。
- 新点在凸包外。
我们回忆一下 Andrew 算法的过程:先将点按
这给了我们启示,如果一个点
将原点集按
考虑用平衡树维护,判断点
在凸包内那么就不用更新凸包。
考虑该点在凸包外的情况。
我们先将该点加入凸包并更新答案。
我们从该点出发,向前后分别扫一遍,将不符合凸包性质的点删除并更新答案。
如果一个点符合凸包性质,那么显然它前或后的点也满足凸包性质,就结束循环。
每个点最多进一次凸包点集,也最多出一次凸包点集,时间复杂度
Code
#include<bits/stdc++.h> using namespace std; #define maxn 100005 struct vec { double x, y; vec(double X=0, double Y=0): x(X), y(Y) {} friend vec operator-(vec a, vec b) {return {a.x-b.x, a.y-b.y}; } friend int cross (vec a, vec b) {return a.x*b.y-a.y*b.x; } auto operator<=> (vec b) const {return x==b.x?y<=>b.y:x<=>b.x;} double length () {return sqrt(x*x+y*y); } }; set<vec> s; double ans; bool chk(vec A) { auto it=s.lower_bound(A); vec B=*it, C=*--it; return cross(B-A, B-C)<=0; } auto pre(set<vec>::iterator it) {return --it;} auto aft(set<vec>::iterator it) {return ++it;} bool erase(set<vec>::iterator it) { if(it==s.begin()) return 0; auto itl=pre(it); auto itr=aft(it); if(itr==s.end()) return 0; vec a=*it-*itl, b=*itr-*it; if(cross(a, b)<0) return 0; ans+=(*itr-*itl).length()-a.length()-b.length(); s.erase(it); return 1; } void insert(vec A) { if(chk(A)) return; auto it=s.insert(A).first; auto pr=pre(it); auto af=aft(it); ans+=(*it-*pr).length()+(*it-*af).length()-(*af-*pr).length(); while(erase(pre(it))); while(erase(aft(it))); } vector<pair<int, int>> vc; vec dts[maxn]; bool del[maxn]; vector<double> Ans; int main() { int n, m, x0, y0; cin>>n>>x0>>y0>>m; for(int i=1;i<=m;i++) cin>>dts[i].x>>dts[i].y; int q; cin>>q; for(int i=1, op, x=0;i<=q;i++) { cin>>op; if(op==1) cin>>x, del[x]=1; vc.emplace_back(op, x); } s.emplace(0, 0); s.emplace(n, 0); s.emplace(x0, y0); ans=vec(x0, y0).length()+vec(x0-n, y0).length(); for(int i=1;i<=m;i++) if(!del[i]) insert(dts[i]); for(auto [op, x]:views::reverse(vc)) { if(op==1) insert(dts[x]); else Ans.emplace_back(ans); } for(auto i:views::reverse(Ans)) printf("%.2lf\n", i); }
本文作者:Jimmy-LEEE
本文链接:https://www.cnblogs.com/redacted-area/p/18379565
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步