bzoj 2300 : [HAOI2011]防线修建
set动态维护凸包
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<cmath> #define N 200005 using namespace std; struct node { int x,y; node(){;} node(int _x,int _y){x=_x;y=_y;} friend bool operator < (const node &aa,const node &bb) { if(aa.x!=bb.x)return aa.x<bb.x; return aa.y<bb.y; } friend node operator - (const node &aa,const node &bb) { return node(aa.x-bb.x,aa.y-bb.y); } friend int operator * (const node &aa,const node &bb) { return aa.x*bb.y-aa.y*bb.x; } friend bool operator == (const node &aa,const node &bb) { return aa.x==bb.x&&aa.y==bb.y; } }q[N]; double dis(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } set<node>s; set<node>::iterator it,st,t1,t2; int n,xx,yy,m; bool v[N]; int qr[N][2],cas; double now; double ans[N]; void add(node p) { it=s.lower_bound(p); node suc=(*it); if(suc==p)return ; --it;st=it; node pre=(*it); if((p-suc)*(pre-suc)<=0)return ; now-=dis(suc,pre); it=s.lower_bound(p); t1=it;++it; while(it!=s.end()) { if((*t1-p)*(*it-p)<0)break; now-=dis(*it,*t1); s.erase(t1); t1=it;++it; } while(st!=s.begin()) { t2=st;--st; if((*t2-p)*(*st-p)>0)break; now-=dis(*t2,*st); s.erase(t2); } s.insert(p); it=st=s.find(p); it--;st++; now+=dis(*it,p);now+=dis(*st,p); return ; } int main() { scanf("%d%d%d",&n,&xx,&yy); s.insert(node(n,0));s.insert(node(0,0)); s.insert(node(xx,yy)); now+=dis(node(xx,yy),node(n,0)); now+=dis(node(xx,yy),node(0,0)); scanf("%d",&m); for(int i=1;i<=m;i++)scanf("%d%d",&q[i].x,&q[i].y); scanf("%d",&cas); for(int i=1;i<=cas;i++) { scanf("%d",&qr[i][0]); if(qr[i][0]==1) { scanf("%d",&qr[i][1]); v[qr[i][1]]=1; } } for(int i=1;i<=m;i++) { if(!v[i])add(q[i]); } for(int i=cas;i>=1;i--) { if(qr[i][0]==2) { ans[i]=now; } else { add(q[qr[i][1]]); } } for(int i=1;i<=cas;i++) { if(qr[i][0]==2)printf("%.2f\n",ans[i]); } return 0; }