bzoj2300 防守战线 平衡树

       我们发现只要倒着操作就可以把删除变成插入了,然后就可以用平衡树维护动态凸包了。(←set水掉的sb)

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#define N 300005
#define sqr(x) (x)*(x)
using namespace std;

struct node{ int x,y; }a[N],c[N];
set<node> s; int n,m; double len,ans[N]; bool bo[N];
int read(){
	int x=0,fu=1; char ch=getchar();
	while (ch<'0' || ch>'9'){ if (ch=='-') fu=-1; ch=getchar(); }
	while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
	return x*fu;
}
node operator -(node u,node v){ u.x-=v.x; u.y-=v.y; return u; }
int crs(node u,node v){ return u.x*v.y-u.y*v.x; }
double dist(node u,node v){
	return sqrt((double)(sqr(u.x-v.x)+sqr(u.y-v.y)));
}
bool operator <(node u,node v){
	return u.x<v.x || u.x==v.x && u.y<v.y;
}
int main(){
	node p; p.x=0; p.y=0; s.insert(p);
	n=p.x=read(); s.insert(p);
	p.x=read(); p.y=read(); s.insert(p);
	len=sqrt((double)(sqr(p.x)+sqr(p.y)))+sqrt((double)(sqr(n-p.x)+sqr(p.y)));
	n=read(); int i,cnt=0;
	for (i=1; i<=n; i++){ a[i].x=read(); a[i].y=read();}
	m=read();
	memset(bo,1,sizeof(bo));
	for (i=1; i<=m; i++){
		c[i].x=read(); if (c[i].x==1){ c[i].y=read(); bo[c[i].y]=0; }
	}
	for (i=1; i<=n; i++) if (bo[i]){ c[++m].x=1; c[m].y=i; }
	set<node>:: iterator l,r,t; 
	for (i=m; i; i--){
		if (c[i].x==1){
			p=a[c[i].y];
			l=r=s.lower_bound(p); l--;
			if (crs(p-*l,*r-*l)<=0){
				len-=dist(*l,*r);
				for (t=r,r++; r!=s.end(); t=r,r++){
					if (crs(*r-p,*t-p)>0) break;
					len-=dist(*r,*t); s.erase(t);
				}
				for (t=l,l--; t!=s.begin(); t=l,l--){
					if (crs(*t-p,*l-p)>0) break;
					len-=dist(*l,*t); s.erase(t);
				}
				s.insert(p); l=r=s.find(p);
				l--; r++; len+=dist(*l,p)+dist(*r,p);
			}
		} else ans[++cnt]=len;
	}
	for (i=cnt; i; i--) printf("%.2f\n",ans[i]);
	return 0;
}


by lych

2016.3.14

你可能感兴趣的:(set,STL,凸包,平衡树,动态凸包)