bzoj2300 防守战线 平衡树

来源:互联网 发布:linux conntrack 编辑:程序博客网 时间:2024/04/28 09:32

       我们发现只要倒着操作就可以把删除变成插入了,然后就可以用平衡树维护动态凸包了。(←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

0 0
原创粉丝点击