http://www.lydsy.com/JudgeOnline/problem.php?id=2300
离线+set维护凸包
第一次码这个,还跑得飞快。。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
int n,m,q;
struct Point{
int x,y;
Point(){}
Point(int x,int y):x(x),y(y){}
Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);}
int operator^(const Point &b)const{return x*b.y-y*b.x;}
bool operator<(const Point &b)const{return x!=b.x?x<b.x:y<b.y;}
}M,a[100010];
struct ques{
int type,x;
}b[200010];
bool del[100010];
set<Point>S;
double ans[200010],nowans;
int tot;
double sqr(double x){return x*x;}
double dis(Point A,Point B)
{
return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));
}
void insert(Point P)
{
set<Point>::iterator L,R=S.lower_bound(P),tmp;
L=R; L--;
if((*R-P^*L-P)>=0) return;
nowans-=dis(*L,*R);
while(L->x!=0)
{
tmp=L; tmp--;
if((P-*L^*tmp-*L)<0) break;
nowans-=dis(*L,*tmp);
S.erase(*L);
L=tmp;
}
while(R->x!=n)
{
tmp=R; tmp++;
if((*tmp-*R^P-*R)<0) break;
nowans-=dis(*R,*tmp);
S.erase(*R);
R=tmp;
}
S.insert(P);
nowans+=dis(*L,P);
nowans+=dis(P,*R);
}
void input()
{
n=read();
M.x=read(); M.y=read();
rep(i,1,m=read()) a[i].x=read(),a[i].y=read();
rep(i,1,q=read())
{
b[i].type=read();
if(b[i].type==1)
{
b[i].x=read();
del[b[i].x]=1;
}
}
S.insert(Point(0,0));
S.insert(Point(n,0));
S.insert(M);
nowans=dis(Point(0,0),M)+dis(M,Point(n,0));
rep(i,1,m) if(!del[i]) insert(a[i]);
}
void solve()
{
per(i,q,1)
{
if(b[i].type==1)
{
insert(a[b[i].x]);
}
else ans[++tot]=nowans;
}
per(i,tot,1) printf("%.2f\n",ans[i]);
}
int main()
{
freopen("_.in","r",stdin); freopen("_.out","w",stdout);
input(),solve();
return 0;
}