BZOJ 2300凸包+离线
思路:
倒着加显然吧 动态维护这个凸包就好了
//By SiriusRen #include <bits/stdc++.h> using namespace std; const int N=200050; int n,m,q,vis[N]; double now; struct Point{int x,y;}point[N],jy,tmp,tt; struct Query{int x,op;double ans;}ask[N]; Point operator-(Point a,Point b){ Point c;c.x=a.x-b.x,c.y=a.y-b.y;return c; } int operator*(Point a,Point b){ return a.x*b.y-a.y*b.x; } bool operator<(Point a,Point b){ if(a.x!=b.x)return a.x<b.x; return a.y<b.y; } double dis(Point a,Point b){ a=a-b;return sqrt(a.x*a.x+a.y*a.y); } set<Point>s;set<Point>::iterator l,r,t; void insert(Point a){ r=s.lower_bound(a),l=r,l--; if((*r-*l)*(a-*l)<0)return; now-=dis((*l),(*r)); s.insert(a),t=r,r++; while(r!=s.end()&&(*r-a)*(*t-a)<0) now-=dis(*t,*r),s.erase(t),t=r,r++; while(l!=s.begin()){ t=l,l--; if((*t-a)*(*l-a)>0)break; now-=dis(*t,*l),s.erase(t); } l=r=t=s.find(a),l--,r++; now+=dis(*l,a)+dis(*r,a); } int main(){ s.insert(tt); scanf("%d%d%d%d",&n,&jy.x,&jy.y,&m); tmp.x=n;now+=dis(tt,jy)+dis(jy,tmp); for(int i=1;i<=m;i++) scanf("%d%d",&point[i].x,&point[i].y); scanf("%d",&q); for(int i=1;i<=q;i++){ scanf("%d",&ask[i].op); if(ask[i].op==1)scanf("%d",&ask[i].x),vis[ask[i].x]=1; }s.insert(jy),s.insert(tmp); for(int i=1;i<=m;i++)if(!vis[i])insert(point[i]); for(int i=q;i;i--){ if(ask[i].op==1)insert(point[ask[i].x]); else ask[i].ans=now; } for(int i=1;i<=q;i++) if(ask[i].op!=1)printf("%.2lf\n",ask[i].ans); }