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 }