bzoj 2300: [HAOI2011]防线修建 平衡树维护凸包

/**************************************************************
    Problem: 2300
    User: wangyucheng
    Language: C++
    Result: Accepted
    Time:564 ms
    Memory:7292 kb
****************************************************************/
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#include<cmath>
using namespace std;
typedef double dd;
typedef long long ll;
#define setp set<P>::iterator 
#define eps 1e-9
#define maxn 220000
struct P{
    int x,y;
    bool operator<(P a)const{
        if(x!=a.x)return x<a.x;
        return y<a.y;
    }
}a[maxn];
set<P> jj;
setp t1,t2,t3;
P make(int x,int y){
   P ans;
   ans.x=x;
   ans.y=y;
   return ans;
}
dd now;
dd dist(P a,P b){
   return sqrt((dd)(a.x-b.x)*(dd)(a.x-b.x)+(dd)(a.y-b.y)*(dd)(a.y-b.y));    
}
ll mul(P a,P b,P c){
    return (ll)(c.x-b.x)*(b.y-a.y)-(ll)(b.x-a.x)*(c.y-b.y);
}
void ins(P a){
    t1=jj.lower_bound(a);
    t2=t1;
    t2--;
    //cout<<"mul="<<mul(*t2,a,*t1)<<endl;
    if(mul(*t2,a,*t1)>0){
         now-=dist(*t1,*t2);
         while(1){
            t3=t1;
            t1++;
            if(t1==jj.end())break;
            if(mul(a,*t3,*t1)>0)break;
            now-=dist(*t3,*t1);
            jj.erase(t3);   
        }   
        while(t2!=jj.begin()){
          t3=t2;
          t2--;
          if(mul(*t2,*t3,a)>0)break;
          now-=dist(*t3,*t2);
          jj.erase(t3); 
        }
        jj.insert(a);
        t1=jj.find(a);
        t3=t2=t1;
        t2++;
        t3--;
        now+=dist(*t3,*t1);
        now+=dist(*t1,*t2);
    }
}
int n,m,x,y,q;
int del[maxn],been[maxn],qq[maxn];
dd ans[maxn];
int main(){
    scanf("%d%d%d",&n,&x,&y);
    jj.insert(make(0,0));
    jj.insert(make(n,0));
    now=n;
    ins(make(x,y));
    scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%d%d",&a[i].x,&a[i].y);
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&qq[i]);
      if(qq[i]==1){scanf("%d",&del[i]);
      been[del[i]]=1;   
    }}
    for(int i=1;i<=m;i++)if(!been[i])ins(a[i]);
    for(int i=q;i>=1;i--){
       if(qq[i]==2){
          ans[i]=now;   
        }else{
           ins(a[del[i]]);  
        }
    }
    for(int i=1;i<=q;i++){
        if(qq[i]==2)printf("%.2f\n",ans[i]);
    }
     
}

 

posted @ 2014-04-02 19:34  wangyucheng  阅读(377)  评论(0编辑  收藏  举报