bzoj 2300 动态维护上凸壳(不支持删除)

新技能GET。

用set保存点,然后只需要找前趋和后继就可以动态维护了。

  1 /**************************************************************
  2     Problem: 2300
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:556 ms
  7     Memory:4824 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cmath>
 12 #include <set>
 13 #define N 100010
 14 #define line(a,b) ((b)-(a))
 15 using namespace std;
 16
 17 struct Job {
 18     int opt, v;
 19     double ans;
 20 };
 21 struct Vector {
 22     int x, y;
 23     void read() { scanf( "%d%d", &x, &y ); }
 24     Vector(){}
 25     Vector( int x, int y ):x(x),y(y){}
 26     Vector operator+( const Vector &b ) const { return Vector(x+b.x,y+b.y); }
 27     Vector operator-( const Vector &b ) const { return Vector(x-b.x,y-b.y); }
 28     int operator^( const Vector &b ) const { return x*b.y-y*b.x; }
 29     double len() { return sqrt(x*x+y*y); }
 30     bool operator<( const Vector &b ) const {
 31         return x<b.x || (x==b.x && y<b.y);
 32     }
 33 };
 34 typedef Vector Point;
 35
 36 int n, m, q;
 37 Point pts[N];
 38 set<Point> cvx;
 39 Job job[N+N];
 40 bool done[N];
 41 double ans;
 42
 43 bool onleft( const Point &a, const Point &b, const Point &c ) {
 44     return (line(a,b) ^ line(a,c)) > 0;
 45 }
 46 void insert( const Point &p ) {
 47     set<Point>::iterator prv, nxt, prev, next;
 48     prv = nxt = cvx.upper_bound( p );
 49     --prv;
 50     if( !onleft(*nxt,p,*prv) ) return;
 51     while( prv!=cvx.begin() ) {
 52         prev = prv;
 53         --prev;
 54         if( !onleft(p,*prv,*prev) ) {
 55             ans += line(*prev,*nxt).len()-line(*prev,*prv).len()-line(*prv,*nxt).len();
 56             cvx.erase(prv);
 57         } else break;
 58         prv = prev;
 59     }
 60     while( nxt!=cvx.end() ) {
 61         next = nxt;
 62         ++next;
 63         if( next==cvx.end() ) break;
 64         if( !onleft(*next,*nxt,p) ) {
 65             ans += line(*prv,*next).len()-line(*prv,*nxt).len()-line(*nxt,*next).len();
 66             cvx.erase(nxt);
 67         } else break;
 68         nxt = next;
 69     }
 70     cvx.insert( p );
 71     ans += line(*prv,p).len()+line(*nxt,p).len()-line(*prv,*nxt).len();
 72 }
 73 int main() {
 74     scanf( "%d", &n );
 75     pts[0].read();
 76     scanf( "%d", &m );
 77     for( int i=1; i<=m; i++ )
 78         pts[i].read();
 79     scanf( "%d", &q );
 80     for( int i=1; i<=q; i++ ) {
 81         scanf( "%d", &job[i].opt );
 82         if( job[i].opt==1 ) {
 83             scanf( "%d", &job[i].v );
 84             done[job[i].v] = true;
 85         }
 86     }
 87     cvx.insert( Point(0,0) );
 88     cvx.insert( pts[0] );
 89     cvx.insert( Point(n,0) );
 90     ans += line(Point(0,0),pts[0]).len() + line(Point(n,0),pts[0]).len();
 91     for( int i=1; i<=m; i++ )
 92         if( !done[i] ) insert( pts[i] );
 93     for( int i=q; i>=1; i-- ) {
 94         if( job[i].opt==1 ) {
 95             insert( pts[job[i].v] );
 96         } else {
 97             job[i].ans = ans;
 98         }
 99     }
100     for( int i=1; i<=q; i++ )
101         if( job[i].opt==2 )
102             printf( "%.2lf\n", job[i].ans );
103 }

时间: 2024-10-10 07:16:58

bzoj 2300 动态维护上凸壳(不支持删除)的相关文章

Share the Ruins Preservation(Graham算法利用叉积动态维护上下凸壳)

Two organizations International Community for Preservation of Constructions (ICPC) and Japanese Archaeologist Group (JAG) engage in ruins preservation. Recently, many ruins were found in a certain zone. The two organizations decided to share the pres

1007: [HNOI2008]水平可见直线[维护下凸壳]

1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7184  Solved: 2741[Submit][Status][Discuss] Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=-x; L3:y=0则L1和L2是可见的,L3是被覆盖的.给

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

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

有趣的凸壳问题~

PART I  BZOJ 1249 1249: SGU277 HERO 动态凸包 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 406  Solved: 123[Submit][Status] Description 平面上最开始只包含3个点,然后还会依次出现N个点.每新增一个点,请你求出包含这些点的周长最小的多边形的面积(也就是凸包的面积). Input 第一行为6个整数,表示最初的三个点的坐标(x1,y1),(x2,y2),(x3,y3).

防线修建 bzoj 2300

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

bzoj 3165: [Heoi2013]Segment 动态凸壳

3165: [Heoi2013]Segment Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 202  Solved: 89[Submit][Status] Description 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i.   2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. Input 第一行一个整数n,表示共n 个操作. 接下来n行,每行第一个数为0或1.

Flink:动态表上的连续查询

用SQL分析数据流 越来越多的公司在采用流处理技术,并将现有的批处理应用程序迁移到流处理或者为新的应用设计流处理方案.其中许多应用程序专注于分析流数据.分析的数据流来源广泛,如数据库交易,点击,传感器测量或物联网设备. Apache Flink非常适合流式分析,因为它提供了事件时间语义支持,恰一次的处理,并同时实现了高吞吐和低延迟.由于这些特性,Flink能够近乎实时地从大量输入流计算确切的和确定性的结果,同时在出现故障时提供恰一次处理的语义. Flink的流处理核心API,DataStream

BZOJ 2300 HAOI 2011 防线修建 动态维护凸包

题目大意:一些成熟分布在第一象限中,现在要建造一个防线来保护他们,但是随着时间的推移,必须要舍弃一些城市,但是不会舍弃首都.问最短的防线需要多长. 思路:在每一个时刻求一个上凸包就是答案了.当然这样做时间复杂度就呵呵了.考虑一下动态维护凸包.因为只有上凸包,所以处理起来会相对方便.我们只需把在凸包中的点按照x坐标排序,然后二分一下把点插入凸包,然后左右用斜率维护一下,这样每次插点的时间复杂度大概是O(logn).但是这样只能插点不能删点,所以离线处理一下,把删点转化为插点,最后倒着输出. (我比

【凸壳】【HNOI 2008】【bzoj 1007】水平可见直线

1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 4567 Solved: 1686 Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线: L1:y=x; L2:y=-x; L3:y=0 则L1和L2是可见的,L3是被覆盖的. 给出n条直线,表示成y=Ax+B的形式(|A|,|