只需要倒着插入,然后维护一个凸包就可以了。
可以用来学习set的用法
#include <map> #include <set> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define inf 100000 #define ll long long #define mp make_pair #define sqr(x) x*x int n,x,y,m,k; struct Vector{ double x,y; void print(){printf("Vector (%.3f,%.3f) ",x,y);} }; struct Point{ int x,y; void print(){printf("Point (%d,%d) ",x,y);} bool operator < (const Point b) const{ return x==b.x?y<b.y:x<b.x; } }a[200005]; set <Point> s; struct Options{int opt,id;}q[200005]; double dist (Point a,Point b) { // printf("dist "); // a.print();b.print(); // printf("The ans is %.6f ",sqr((double)a.x-b.x)+sqr((double)a.y-b.y)); return sqrt(((double)a.x-b.x)*((double)a.x-b.x)+((double)a.y-b.y)*((double)a.y-b.y)); } Vector operator - (Point a,Point b) {Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;} double operator * (Vector a,Vector b) { // a.print(); printf("* * * "); // b.print(); // printf("= %.6f ",a.x*b.y-a.y*b.x); return a.x*b.y-a.y*b.x; } int tot,del[200005]; double ans[200005],now; Point newnode; void init() { now=n*1.0; newnode.x=0;newnode.y=0; s.insert(newnode); // newnode.x=0;newnode.y=-inf; // s.insert(newnode); newnode.x=n;newnode.y=0; s.insert(newnode); // newnode.x=n;newnode.y=-inf; // s.insert(newnode); // printf("now is %.6f ",now); } void add(Point x) { // printf("Add "); x.print(); set<Point>::iterator it,iL,iR; it=s.lower_bound(x); iL=it;iL--;iR=it; if ((x-*iL)*(*iR-x)>0) return; // printf("New node "); now-=dist(*iL,*iR); for (;;) { iR=it;it++; if (it==s.end()) break; if ((*iR-x)*(*it-x)>0) { now-=dist(*iR,*it); s.erase(*iR); // printf("del R "); while (1); } else break; } for (;;) { if (iL==s.begin()) break; Point L=*iL; iL--; // (*iL-*it).print(); // (*it-x).print(); if ((L-*iL)*(x-*iL)>0) { now-=dist(*iL,L); s.erase(L); // printf("del L "); //while(1); } else break; } s.insert(x); it=s.find(x); iL=it;iL--;iR=it;iR++; now+=dist(*iL,x)+dist(x,*iR); // printf("now is %.6f ",now); return ; } void Finout() { freopen("defense.in","r",stdin); freopen("defense.out","w",stdout); } int main() { // freopen("in.txt","r",stdin); scanf("%d%d%d",&n,&x,&y); scanf("%d",&m); F(i,1,m) scanf("%d%d",&a[i].x,&a[i].y); scanf("%d",&k); // printf("k is %d ",k); F(i,1,k) { scanf("%d",&q[i].opt); switch(q[i].opt) { case 1:scanf("%d",&q[i].id); del[q[i].id]=1;break; case 2:q[i].id=++tot; break; } } // F(i,1,k) printf("Opt %d id %d ",q[i].opt,q[i].id); init(); newnode.x=x;newnode.y=y;add(newnode); F(i,1,m) if (!del[i]) add(a[i]); D(i,k,1) { switch(q[i].opt) { case 1:add(a[q[i].id]);break; case 2:ans[q[i].id]=now;break; } } F(i,1,tot) printf("%.2f ",ans[i]); }