上凸包最好用水平排序做,如果用极角序会很难做。
坑点:set erase一个元素之后,其他元素的指针不改变。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
typedef pair<lint,lint> pii;
const int maxn = 100001;
const double eps = 1e-12;
const double PI = acos(-1.0);
int sgn(double x)
{
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{ x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x; }
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y; }
//绕原点旋转角度B(弧度值),后x,y的变化
bool operator <( const Point& b )const{
if( x == b.x ) return y < b.y;
return x < b.x;
}
};
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
int dist2(Point a,Point b)
{
return (a-b)*(a-b);
}
const lint maxq = 200005;
pii Q[maxq];
lint vis[maxn];
Point p[maxn];
double ans[maxq],res;
set<Point> se;
void Insert( Point x ) {
auto p = se.lower_bound(x);
auto r = p,l = p;
l--;
if( ((x-*l)^(*r-*l)) >= 0 ) return;
res -= dist(*l,*r);
auto t = r;t++;
while( t != se.end() ){
if( ((*t-x)^( *t-*r )) <= 0 ) break;
auto c = r;
res -= dist( *r,*t );
r++;t++;
se.erase( c );
}
res += dist( x,*r );
if( l != se.begin() ){
t = l;t--;
while( l != se.begin() ){
if( ((*t-*l)^(*t-x))<= 0 ) break;
res -= dist( *l,*t );
auto c = l;
l--;t--;
se.erase(c);
}
}
res += dist( *l,x );
se.insert(x);
}
int main(){
lint n,x,y;
scanf("%d%d%d",&n,&x,&y);
se.insert( Point(0,0) );se.insert(Point(x,y));se.insert(Point(n,0));
res = dist( Point(x,y),Point(n,0) ) + dist( Point(0,0),Point(x,y) );
lint m,tot = 1,q;
scanf("%d",&m);
for( lint x,y,i = 1;i <= m;i++ ){
scanf("%d%d",&x,&y);
p[tot++] = Point(x,y);
}
scanf("%d",&q);
for( lint f,x,i = 1;i <= q;i++ ){
scanf("%d",&f);
if( f == 1 ){
scanf("%d",&x);
Q[i] = pii( f,x );
vis[x] = 1;
}else{
Q[i] = pii( f,0 );
}
}
for( lint i = 1;i <= m;i++ ){
if(vis[i]) continue;
Insert(p[i]);
}
for( lint i = q;i >= 1;i-- ){
if( Q[i].first == 1 ){
Insert( Point( p[Q[i].second] ) );
}else{
ans[i] = res;
}
}
for( lint i = 1;i <= q;i++ ){
if( Q[i].first == 2 )
printf("%.2lf\n",ans[i]);
}
return 0;
}