[BZOJ2300]防線修建
阿新 • • 發佈:2017-08-16
沒有 == name fin main break sqrt ace for
第一次寫水平序凸包,感覺跟極角序凸包差不多
凸包的刪除看上去不太可做,但我們發現這題沒有強制在線,所以我們離線統計答案
離線之後把操作反序,刪除就變為插入了
用平衡樹維護凸包,每插入一個點,就不停刪除它左右兩邊不滿足凸包性質的點
每個點只會被插入刪除各一次,不會超時
1 #include<stdio.h>
2 #include<math.h>
3 #include<set>
4 using namespace std;
5 const double eps=1e-8;
6 struct point{
7 double x,y;
8 point(double a=.0,double b=.0){
9 x=a;
10 y=b;
11 }
12 }c[100010],cc;
13 bool operator<(point a,point b){
14 if(a.x==b.x)return a.y<b.y;
15 return a.x<b.x;
16 }
17 set<point>s,tmp;
18 set<point>::iterator ita,itb,it;
19 int ask[200010];
20 double ans,tans[200010 ];
21 double dist(point a,point b){
22 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
23 }
24 double cross(double x1,double y1,double x2,double y2){
25 return x1*y2-y1*x2;
26 }
27 void insert(point x){
28 ita=s.lower_bound(x);
29 itb=ita;
30 ita--;
31 if(cross(x.x-ita->x,x.y-ita->y,itb->x-x.x,itb->y-x.y)>=-eps)return ;
32 ans-=dist(*ita,*itb);
33 while(ita!=s.begin()){
34 it=ita;
35 it--;
36 if(cross(ita->x-it->x,ita->y-it->y,x.x-ita->x,x.y-ita->y)>=-eps){
37 ans-=dist(*ita,*it);
38 cc=*it;
39 s.erase(ita);
40 ita=s.find(cc);
41 }else
42 break;
43 }
44 it=itb;
45 it++;
46 while(it!=s.end()){
47 if(cross(itb->x-x.x,itb->y-x.y,it->x-itb->x,it->y-itb->y)>=-eps){
48 ans-=dist(*it,*itb);
49 cc=*it;
50 s.erase(itb);
51 itb=s.find(cc);
52 }else
53 break;
54 it=itb;
55 it++;
56 }
57 ans+=dist(x,*ita)+dist(x,*itb);
58 s.insert(x);
59 }
60 int main(){
61 int i,a,b,m,q;
62 scanf("%d%d%d",&i,&a,&b);
63 ans=dist(point(),point(a,b))+dist(point(i,0),point(a,b));
64 s.insert(point());
65 s.insert(point(i,0));
66 s.insert(point(a,b));
67 scanf("%d",&m);
68 for(i=1;i<=m;i++){
69 scanf("%lf%lf",&c[i].x,&c[i].y);
70 tmp.insert(c[i]);
71 }
72 scanf("%d",&q);
73 for(i=1;i<=q;i++){
74 scanf("%d",&a);
75 if(a==1){
76 scanf("%d",ask+i);
77 tmp.erase(c[ask[i]]);
78 }
79 }
80 for(it=tmp.begin();it!=tmp.end();it++)insert(*it);
81 for(i=q;i>0;i--){
82 if(ask[i])
83 insert(c[ask[i]]);
84 else
85 tans[i]=ans;
86 }
87 for(i=1;i<=q;i++){
88 if(ask[i]==0)printf("%.2lf\n",tans[i]);
89 }
90 }
[BZOJ2300]防線修建