正常的splay维护凸包不支持删点,把操作倒过来变成加点。
HAOI真心良心呀,边界都给好了。。。
#include <bits/stdc++.h>
using namespace std;
#define N 110000
#define M 210000
#define which(x) (ch[fa[x]][1]==x)
int d,n,Q,root;
int X[N],Y[N],vis[N],tp[M],v[M];
int pre[N],nex[N],fa[N],ch[N][2];
double ans,fin[M];
void rotate(int x)
{
int y=fa[x],k=which(x);
ch[y][k]=ch[x][k^1];
ch[x][k^1]=y;
ch[fa[y]][which(y)]=x;
fa[x]=fa[y];fa[y]=x;
fa[ch[y][k]]=y;
}
void splay(int x,int tar)
{
while(fa[x]!=tar)
{
int y=fa[x];
if(fa[y]==tar)rotate(x);
else
{
if(which(x)^which(y))rotate(x);
else rotate(y);
rotate(x);
}
}
if(!tar)root=x;
}
void f_pre(int x,int v,int &ret)
{
if(!x)return;
if(X[x]<=v)
{
ret=X[x]>X[ret] ? x:ret;
f_pre(ch[x][1],v,ret);
}
else f_pre(ch[x][0],v,ret);
}
void f_nex(int x,int v,int &ret)
{
if(!x)return;
if(X[x]>v)
{
ret=X[x]<X[ret] ? x:ret;
f_nex(ch[x][0],v,ret);
}
else f_nex(ch[x][1],v,ret);
}
double dis(int x,int y)
{return sqrt((X[x]-X[y])*(X[x]-X[y])+(Y[x]-Y[y])*(Y[x]-Y[y]));}
void del(int x)
{
splay(pre[x],0);
splay(nex[x],root);
ch[nex[x]][0]=0;
nex[pre[x]]=nex[x];pre[nex[x]]=pre[x];
}
void ins(int x)
{
int l=1,r=2;
f_pre(root,X[x],l);f_nex(root,X[x],r);
if((Y[x]-Y[l])*(X[r]-X[l])<(Y[r]-Y[l])*(X[x]-X[l]))return;
ans-=dis(l,r);
while(l!=1&&(Y[l]-Y[pre[l]])*(X[x]-X[l])<(Y[x]-Y[l])*(X[l]-X[pre[l]]))
del(l),ans-=dis(l,pre[l]),l=pre[l];
while(r!=2&&(Y[r]-Y[x])*(X[nex[r]]-X[r])<(Y[nex[r]]-Y[r])*(X[r]-X[x]))
del(r),ans-=dis(r,nex[r]),r=nex[r];
nex[l]=x;pre[x]=l;
pre[r]=x;nex[x]=r;
ans+=dis(l,x);ans+=dis(r,x);
splay(pre[x],0);
splay(nex[x],root);
ch[nex[x]][0]=x;fa[x]=nex[x];
splay(x,0);
}
int main()
{
scanf("%d%d%d",&d,&X[3],&Y[3]);
scanf("%d",&n);X[2]=d;
for(int i=1;i<=n;i++)scanf("%d%d",&X[i+3],&Y[i+3]);
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
{
scanf("%d",&tp[i]);
if(tp[i]==1)scanf("%d",&v[i]),vis[v[i]]=1;
}
pre[3]=1;nex[3]=2;root=3;
ch[3][0]=1;ch[3][1]=2;fa[1]=fa[2]=3;
ans=dis(3,1)+dis(3,2);
for(int i=1;i<=n;i++)
if(!vis[i])ins(i+3);
for(int i=Q;i>=1;i--)
{
if(tp[i]==1)ins(v[i]+3);
else fin[i]=ans;
}
for(int i=1;i<=Q;i++)
if(tp[i]==2)printf("%.2lf\n",fin[i]);
return 0;
}