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]); } }