首页 > 代码库 > poj 1151-atlantis-线段树扫描线求面积并

poj 1151-atlantis-线段树扫描线求面积并

 = =||好像放在草稿箱里长毛了~~~~~本来想写个好详细好详细的扫描线哒~~~可是看到代码都不想动了,再跟别的大牛的代码一比较,觉得自己这单点更新简直就是纯暴力伪线段树吖~~~还有那离散化【离散了还用函数去O(n)地找是怎么回事啊喂!】如果题目范围是10000个点估计我就布吉岛爆到哪里去了。。。。。所以还是不要教坏小孩子了~~看到这篇日志的童鞋默默转台就好。。。。其实100个点乖乖按线段存然后暴力就好~~~~吐槽完毕~~以上!

AC代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <algorithm>  4 #include <vector>  5 using namespace std;  6 #define maxn 300  7 #define lson l, m, rt<<1  8 #define rson m+1, r, rt<<1|1  9 struct st 10 { 11     int cover; 12     double len; 13 }; 14 vector<st> sgt; 15 int n; 16 struct Line 17 { 18     double x, y_up, y_down; 19     int sign; 20     bool operator < (const Line that) const { 21         return x < that.x; 22     } 23 }; 24 vector<Line> line; 25 vector<double> Y; 26 void input() 27 { 28     line.clear(); 29     Y.clear(); 30     sgt.clear(); 31     sgt.resize(maxn<<1); 32     double x, y, a, b; 33     Line read; 34     scanf("%lf%lf%lf%lf", &x, &y, &a, &b); 35     read.x = x; read.sign = 1; read.y_down = y; read.y_up = b; 36     line.push_back(read); Y.push_back(y); 37     read.x = a; read.sign = -1; 38     line.push_back(read); Y.push_back(b); 39     for(int i = 1; i < n; i++) { 40         scanf("%lf%lf%lf%lf", &x, &y, &a, &b); 41         read.x = x; read.sign = 1; read.y_down = y; read.y_up = b; 42         line.push_back(read); 43         read.x = a; read.sign = -1; 44         line.push_back(read); 45         bool flag1 = 0, flag2 = 0; int l = Y.size(); 46         for(int j = 0; j < l; j++) { 47             if(Y[j] == y) flag1 = 0; 48             if(Y[j] == b) flag2 = 0; 49          } 50          if(!flag1) Y.push_back(y); 51          if(!flag2) Y.push_back(b); 52     } 53     sort(line.begin(), line.end()); 54     sort(Y.begin(), Y.end()); 55 } 56  57 void build(int l, int r, int rt) 58 { 59     sgt[rt].cover = 0; 60     sgt[rt].len = 0; 61     if(l == r) { 62         sgt[rt].len = Y[l] - Y[l-1]; 63         return; 64     } 65     int m = (l + r)>>1; 66     build(lson); 67     build(rson); 68 } 69 void insert(int l, int r, int rt, int L, int R, int sign) 70 { 71     if(l == r) { 72         sgt[rt].cover += sign; 73         return; 74     } 75     sgt[rt].len = 0; 76     int m = (l+r)>>1; 77     if(L <= m)  insert(lson, L, R, sign); 78     if(m < R)  insert(rson, L, R, sign); 79 } 80 double getSum(int l, int r, int rt) 81 { 82     if(l == r) { 83         if(sgt[rt].cover > 0) return sgt[rt].len; 84         return 0; 85     } 86     int m = (l + r)>>1; 87     double a, b, ans; 88     ans = getSum(lson); 89     ans += getSum(rson); 90     return ans; 91 } 92 struct node 93 { 94     int st, nd; 95 }; 96 node getNum(double y1, double y2) 97 { 98     int l = Y.size(); 99     node res;100     for(int i = 0; i < l; i++) {101         if(Y[i] == y1) res.st = i+1;102         if(Y[i] == y2) res.nd = i;103     }104     return res;105 }106 void work(int cas)107 {108     input();109     int N = Y.size();110     build(1, N-1, 1);111     int l = line.size();112     double ans = 0;113     for(int i = 0; i < l; i++) {114         node rec = getNum(line[i].y_down, line[i].y_up);115         if(i == 0) insert(1, N-1, 1, rec.st, rec.nd, line[i].sign );116         if(i == 0) continue;117         double length = line[i].x - line[i-1].x;118         ans += length*getSum(1, N-1, 1);119         insert(1, N-1, 1, rec.st, rec.nd, line[i].sign );120     }121     printf("Test case #%d\nTotal explored area: %0.2f\n\n", cas, ans);122 }123 int main()124 {125     int cnt = 0;126     while(1) {127         scanf("%d", &n); if(n == 0) break;128         work(++cnt);129     }130     return 0;131 }
View Code

 

poj 1151-atlantis-线段树扫描线求面积并