就是叉积乱搞 set水过
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=200005;
inline double sqr(int x){ return (double)x*x; }
struct Point{
int x,y;
Point(int x=0,int y=0):x(x),y(y) { }
friend istream& operator >> (istream &_,Point &x){ read(x.x); read(x.y); return _; }
friend bool operator < (Point A,Point B){ return A.x==B.x?A.y<B.y:A.x<B.x; }
friend int operator * (Point A,Point B){ return A.x*B.y-A.y*B.x; }
friend Point operator - (Point A,Point B){ return Point(A.x-B.x,A.y-B.y); }
friend double dist(Point A,Point B){ return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y)); }
}b[N],a[N];
int del[N],tot;
set<Point> Set;
typedef set<Point>::iterator ITER;
int n,m;
double Ans,ans[N];
int Q,que[N],qtot;
inline void Ins(Point x){
ITER r=Set.lower_bound(x),l=r,t;
l--;
if((*r-*l)*(x-*l)<0) return;
Ans-=dist(*l,*r);
Set.insert(x);
while (1)
{
t=r; r++;
if(r==Set.end()) break;
if((*r-x)*(*t-x)>0) break;
Ans-=dist(*t,*r);
Set.erase(t);
}
while (1)
{
if (l==Set.begin()) break;
t=l; l--;
if((*t-x)*(*l-x)>0) break;
Ans-=dist(*t,*l);
Set.erase(t);
}
Set.insert(x);
l=r=Set.find(x);
l--; r++;
Ans+=dist(*l,x)+dist(*r,x);
}
int main()
{
Point tmp; int order,x; read(m); cin>>tmp;
Set.insert(Point(0,0)); Set.insert(Point(m,0)); Set.insert(tmp);
Ans+=dist(Point(0,0),tmp); Ans+=dist(Point(m,0),tmp);
read(n);
for (int i=1;i<=n;i++) cin>>a[i];
read(Q);
for (int i=1;i<=Q;i++){
read(order);
if (order==1){
read(x); del[x]=1; b[++tot]=a[x];
}else{
que[++qtot]=tot;
}
}
for (int i=1;i<=n;i++) if (!del[i]) Ins(a[i]);
for (int i=qtot;i;i--)
{
while (tot>que[i])
Ins(b[tot--]);
ans[i]=Ans;
}
for (int i=1;i<=qtot;i++)
printf("%.2lf\n",ans[i]);
return 0;
}