每次删一个点或询问剩余点的凸包周长
删一个点好麻烦呀,考虑离线,倒着操作将删点改为加点
然后就简单了,用一颗平衡树维护凸包中的点,倒着把点加回去
splay可以用set
论熟练运用STL
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define inf 1e9
using namespace std;
const int maxn = 110000;
struct node
{
int x,y;
node(){}
node(int _x,int _y){x=_x;y=_y;}
}a[maxn],up,zero; int n;
int mul(node x,node y)
{
return x.x*y.y-x.y*y.x;
}
int multi(node x,node y,node z)
{
x.x-=z.x; x.y-=z.y;
y.x-=z.x; y.y-=z.y;
return x.x*y.y-x.y*y.x;
}
bool judge(node x,node y){ return x.x==y.x&&x.y==y.y; }
bool operator <(node x,node y)
{
return mul(x,y)>0||(mul(x,y)==0&&x.x<y.x);
}
double dis(node x,node y)
{
double x1=x.x-y.x,y1=x.y-y.y;
return sqrt((x1*x1)+(y1*y1));
}
stack<double> T;
bool vis[maxn];
int q[maxn];
int m;
double ret;
set<node>S;
set<node>::iterator it;
void ins(node x)
{
it=S.lower_bound(x);
set<node>::iterator l,r,ll,rr;
r=it;
it--; l=it;
if(mul(*r,x)==0) return ;
if(judge(*r,up))
{
ll=l; ll--;
if(multi(*l,*ll,x)<0)
{
S.insert(x);
ret+=dis(zero,x)+dis(x,*l)-dis(zero,*l);
return ;
}
ret-=dis(zero,*l);
for(;!judge(*ll,zero);l=ll,ll--)
{
if(multi(*l,*ll,x)<0) break;
ret-=dis(*l,*ll);
S.erase(*l);
}
S.insert(x);
ret+=dis(x,zero)+dis(x,*l);
return ;
}
if(multi(x,*r,*l)<=0) return ;
ret-=dis(*l,*r);
for(rr=r,rr++;!judge(*rr,up);r=rr,rr++)
{
if(multi(*r,*rr,x)>0) break;
ret-=dis(*r,*rr);
S.erase(*r);
}
ret+=dis(x,*r);
for(ll=l,ll--;!judge(*ll,zero);l=ll,ll--)
{
if(multi(*l,x,*ll)>0) break;
ret-=dis(*l,*ll);
S.erase(*l);
}
ret+=dis(x,*l);
S.insert(x);
}
int main()
{
int x,y,c; scanf("%d%d%d",&c,&x,&y);
node zero=node(0,0); S.insert(zero);
node a2=node(c,0); S.insert(a2);
node a3=node(x,y); S.insert(a3);
up=node(0,1);
S.insert(up);
ret=dis(a2,a3)+dis(zero,a3);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
a[i]=node(x,y);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(x==2) q[i]=0;
else scanf("%d",&q[i]),vis[q[i]]=true;
}
for(int i=1;i<=n;i++) if(!vis[i]) ins(a[i]);
for(int i=m;i>=1;i--)
{
if(!q[i]) T.push(ret);
else ins(a[q[i]]);
}
while(!T.empty()) printf("%.2lf\n",T.top()),T.pop();
return 0;
}