poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并

题目链接:http://poj.org/problem?id=1177

题意:给出n个矩形,求周长并

思路:第一种方法和矩形面积并差不多。

先做一次对x坐标离散化,然后从下往上扫描,每扫描到一条线段,更新线段树,然后答案加上该次的整个区间被覆盖的长度与上次的差的绝对值。

再做一次对y坐标离散化,然后从左往右扫描,每扫描到一条线段,更新线段树,然后答案加上该次的整个区间被覆盖的长度与上次的差的绝对值。

poj上可以A,不知道为什么hdu上交G++是wa,交C++就A了。。。

  1 //#include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <string>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <map>
  9 using namespace std;
 10 int n;
 11 #define maxn 10010
 12 #define lson l, m, rt<<1
 13 #define rson m+1, r, rt<<1|1
 14 struct Seg
 15 {
 16     int x1, y1, x2, y2;
 17 }seg[maxn];
 18 struct Line
 19 {
 20     int l, r, h;
 21     int mark;
 22 }line[maxn];
 23 int a[maxn], b[maxn];
 24 map <int, int> mp;
 25 int cnt;
 26 int ans;
 27 bool cmp(Line l1, Line l2)
 28 {
 29     return l1.h < l2.h;
 30 }
 31 int sum[(maxn*2)<<2];
 32 int cover[(maxn*2)<<2];
 33 void pushup(int l, int r, int rt)
 34 {
 35     if(sum[rt]) cover[rt] = mp[r+1] - mp[l];
 36     else
 37     {
 38         if(r == l) cover[rt] = 0;
 39         else cover[rt] = cover[rt<<1] + cover[rt<<1|1];
 40     }
 41 }
 42 void build(int l, int r, int rt)
 43 {
 44     cover[rt] = 0; sum[rt] = 0;
 45     if(l == r) return;
 46     int m = (l+r)>>1;
 47     build(lson);
 48     build(rson);
 49     pushup(l, r, rt);
 50 }
 51 void update(int L, int R, int val, int l, int r, int rt)
 52 {
 53     if(L == l && R == r)
 54     {
 55         sum[rt] += val;
 56         pushup(l, r, rt);
 57         return;
 58     }
 59     int m = (l+r)>>1;
 60     if(R <= m) update(L, R, val, lson);
 61     else if(L > m) update(L, R, val, rson);
 62     else
 63     {
 64         update(L, m, val, lson);
 65         update(m+1, R, val, rson);
 66     }
 67     pushup(l, r, rt);
 68 }
 69 void slovex()
 70 {
 71     cnt = 0; mp.clear();
 72     for(int i = 1; i <= n; i++)
 73     {
 74         a[cnt++] = seg[i].x1; a[cnt++] = seg[i].x2;        
 75         line[i*2-1].l = seg[i].x1; line[i*2-1].r = seg[i].x2;
 76         line[i*2-1].h = seg[i].y1; line[i*2-1].mark = 1;        
 77         line[i*2].l = seg[i].x1; line[i*2].r = seg[i].x2;
 78         line[i*2].h = seg[i].y2; line[i*2].mark = -1;
 79     }
 80     for(int i = 0; i < cnt; i++) b[i] = a[i];
 81     sort(a, a+cnt);
 82     int precnt = cnt; 
 83     cnt = unique(a, a+cnt) - a;
 84     for(int i = 0; i < precnt; i++) mp[lower_bound(a, a+cnt, b[i]) - a + 1] = b[i];
 85     sort(line+1, line+1+2*n, cmp);
 86     build(1, cnt, 1);
 87     int precover = 0;
 88     for(int i = 1; i <= 2*n; i++)
 89     {
 90         int ll = lower_bound(a, a+cnt, line[i].l) - a + 1;
 91         int rr = lower_bound(a, a+cnt, line[i].r) - a + 1;
 92         update(ll, rr-1, line[i].mark, 1, cnt, 1);
 93         ans += abs(precover - cover[1]);
 94         precover = cover[1];
 95     }
 96 }
 97 void slovey()
 98 {
 99     cnt = 0; mp.clear();
100     for(int i = 1; i <= n; i++)
101     {
102         a[cnt++] = seg[i].y1; a[cnt++] = seg[i].y2;   
103         line[i*2-1].l = seg[i].y1; line[i*2-1].r = seg[i].y2;
104         line[i*2-1].h = seg[i].x1; line[i*2-1].mark = 1;   
105         line[i*2].l = seg[i].y1; line[i*2].r = seg[i].y2;
106         line[i*2].h = seg[i].x2; line[i*2].mark = -1;
107     }
108     for(int i = 0; i < cnt; i++) b[i] = a[i];
109     sort(a, a+cnt);
110     int precnt = cnt;
111     cnt = unique(a, a+cnt) - a;
112     for(int i = 0; i < precnt; i++) mp[lower_bound(a, a+cnt, b[i]) - a + 1] = b[i];
113     sort(line+1, line+1+2*n, cmp);
114     build(1, cnt, 1);
115     int precover = 0;
116     for(int i = 1; i <= 2*n; i++)
117     {
118         int ll = lower_bound(a, a+cnt, line[i].l) - a + 1;
119         int rr = lower_bound(a, a+cnt, line[i].r) - a + 1;
120         update(ll, rr-1, line[i].mark, 1, cnt, 1);
121         ans += abs(precover - cover[1]);
122         precover = cover[1];
123     }
124 }
125 int main() 
126 {
127     //freopen("in.txt", "r", stdin);
128     //freopen("out.txt", "w", stdout);
129     int cast = 0;
130     while(~scanf("%d", &n))
131     {
132         cnt = 0; mp.clear();
133         for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &seg[i].x1, &seg[i].y1, &seg[i].x2, &seg[i].y2);
134         ans = 0;
135         slovex(); slovey();
136         printf("%d\n", ans);
137     }
138     return 0;
139 }

 

posted @ 2016-05-25 22:38  下周LGD该赢了吧  阅读(157)  评论(0编辑  收藏  举报