[BZOJ2300]防线修建

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

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

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

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

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

 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 }
时间: 2024-07-30 14:24:56

[BZOJ2300]防线修建的相关文章

bzoj-2300 防线修建

题意: 给出一个点集,每次可能删去一个点或查询上凸包的面积: 保证无重点,保证最左面 最右面的点一定在凸包上: n<=100000,m<=200000: 题解: 动态凸包问题,然而这道题的保证简直极为良心: 所以呢,我们就可以用set来水这道题啦: 我还是涨了不少姿势的,比如迭代器居然可以自减: 离线所有的操作之后处理,就是凸包加点了: 每次来一个点,判断一下加不加入,之后左面干点右面干点,插进去就好了: 不过这题细节还是用很多,主要是边界问题吧: 时间复杂度O(set(n))O(nlogn)

【BZOJ2300】[HAOI2011]防线修建 set维护凸包

[BZOJ2300][HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于A国的经费有限,所以希望你能帮忙完成如下的一个任务: 1.给出你所有的A国城市坐标 2.A国上层经过讨论,考虑到经济问题,决定取消对i城市的保护,也就是说i城市不需要在防线内了 3.A国上层询问对于剩下要保护的城市,修建防线的总经费最少

bzoj千题计划236:bzoj2300: [HAOI2011]防线修建

http://www.lydsy.com/JudgeOnline/problem.php?id=2300 维护动态凸包,人懒用的set 用叉积判断,不要用斜率 #include<set> #include<cmath> #include<cstdio> #include<iostream> using namespace std; #define N 100001 struct node { int x,y; node(int x_=0,int y_=0):

防线修建 bzoj 2300

防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于A国的经费有限,所以希望你能帮忙完成如下的一个任务: 1.给出你所有的A国城市坐标 2.A国上层经过讨论,考虑到经济问题,决定取消对i城市的保护,也就是说i城市不需要在防线内了 3.A国上层询问对于剩下要保护的城市,修建防线的总经费最少是多少 你需要对

BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )

离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) ----------------------------------------------------------------------- #include<cmath> #include<cstdio> #include<cctype> #include<cstring> #include<cstdlib> #include<algori

【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)

2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于A国的经费有限,所以希望你能帮忙完成如下的一个任务: 1.给出你所有的A国城市坐标 2.A国上层经过讨论,考虑到经济问题,决定取消对i城市的保护,也就是说i城市不需要在防线内了 3.A国上层询问对于剩下要保护的城市,修建防线的总经费最少是多少

【题解】P2521 [HAOI2011]防线修建(动态凸包)

[题解]P2521 [HAOI2011]防线修建(动态凸包) 凸包是易插入不好删除的东西,按照剧情所以我们时光倒流 然后问题就是维护凸包的周长,支持加入 本来很简单,但是计算几何就是一些小地方经验不足容易WA和RE 然后代码注释里有一些经验 //@winlere #include<iostream> #include<set> #include<cstdio> #include<cstring> #include<algorithm> #incl

bzoj2300【HAOI2011】防线修建

题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于A国的经费有限,所以希望你能帮忙完成如下的一个任务: 1.给出你所有的A国城市坐标 2.A国上层经过讨论,考虑到经济问题,决定取消对i城市的保护,也就是说i城市不需要在防线内了 3.A国上层询问对于剩下要保护的城市,修建防线的总经费最少是多少 你需要对每次询问作出回答.注意单位1长度的防线花费为1.

BZOJ-2300 [HAOI2011]防线修建

将问题离线倒序处理,问题变成动态加点维护凸包. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <cctype> #include <set> #define rep(i, l, r) for(int i=l; i&