码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ2300]防线修建

时间:2017-08-16 15:20:17      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:else   can   amp   oid   class   i++   zoj   超时   ras   

第一次写水平序凸包,感觉跟极角序凸包差不多

凸包的删除看上去不太可做,但我们发现这题没有强制在线,所以我们离线统计答案

离线之后把操作反序,删除就变为插入了

用平衡树维护凸包,每插入一个点,就不停删除它左右两边不满足凸包性质的点

每个点只会被插入删除各一次,不会超时

 

 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]防线修建

标签:else   can   amp   oid   class   i++   zoj   超时   ras   

原文地址:http://www.cnblogs.com/jefflyy/p/7373181.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!