传送门
参考博客
练习
S
T
L
STL
STL库。动态维护凸包。由于题目要求一个一个删除,可以考虑反过来离线操作,一个一个加回去。
当新增加一个点的时候,往它的左右两边扩张(
s
e
t
set
set中按照
x
x
x排好序),看是否需要修改凸包。用叉积判断即可。
注意最开始要加上
d
i
s
(
(
0
,
0
)
,
(
x
,
y
)
)
dis((0,0),(x,y))
dis((0,0),(x,y))和
d
i
s
(
(
m
,
0
)
,
(
x
,
y
)
)
dis((m,0),(x,y))
dis((m,0),(x,y))。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxq=2e5+10;
int del[maxn],tot=0,n,q;double ans[maxq],cur=0.0,m,x,y;
struct Grid{
double x,y;
Grid(double X=0,double Y=0){x=X,y=Y;}
friend inline Grid operator+(const Grid &a,const Grid &b){return Grid(a.x+b.x,a.y+b.y);}
friend inline Grid operator-(const Grid &a,const Grid &b){return Grid(a.x-b.x,a.y-b.y);}
friend inline Grid operator*(const Grid &a,const double &b){return Grid(a.x*b,a.y*b);}
friend inline Grid operator/(const Grid &a,const double &b){return Grid(a.x/b,a.y/b);}
friend inline double cross(const Grid &a,const Grid &b){return a.x*b.y-a.y*b.x;}
friend inline double dis(const Grid &a,const Grid &b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
friend inline bool operator<(const Grid &a,const Grid &b)
{return (a.x==b.x)?a.y<b.y:a.x<b.x;}
inline void print(){printf("%.2lf %.2lf\n",x,y);}
}p[maxn];typedef Grid Vector,Point;
struct question{
int op,id;
question(int OP=0,int ID=0){op=OP,id=ID;}
}Q[maxq];
set<Point> G;
inline void add(Point x){
set<Point>::iterator l,r,t;
l=r=G.upper_bound(x),--l;
Point A=*l,B=*r;
if(cross(B-x,A-x)>0) return;
cur-=dis(*l,*r);
while(l!=G.begin()){
t=l,--t;if(cross(*l-x,*t-x)>0) break;
cur-=dis(*l,*t),G.erase(*l),l=t;
}
while(1){
t=r,++t;
if(t==G.end()||cross(*t-x,*r-x)>0) break;
cur-=dis(*r,*t),G.erase(*r),r=t;
}
G.insert(x),l=r=G.find(x),--l,++r;
cur+=dis(x,*l)+dis(x,*r);
}
int main(){
//freopen("1968.in","r",stdin);
scanf("%lf%lf%lf",&m,&x,&y);
G.insert(Point(0,0)),G.insert(Point(m,0)),G.insert(Point(x,y));
cur+=dis(Point(0,0),Point(x,y))+dis(Point(m,0),Point(x,y));
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%d",&q);
for(int i=1;i<=q;++i){
scanf("%d",&Q[i].op);
if(Q[i].op==1) scanf("%d",&Q[i].id),del[Q[i].id]=1;
}for(int i=1;i<=n;++i) if(!del[i]) add(p[i]);
for(int i=q;i>=1;i--){
if(Q[i].op==2) ans[++tot]=cur;
else add(p[Q[i].id]);
}
for(int i=tot;i>=1;--i)
printf("%.2lf\n",ans[i]);
}