IOI1998 hdu1828 poj1177 Picture

写了一发扫描线竟然狂WA不止,hdu死活过不了,poj和当时IOI的数据(还花了我1dsdn积分。。)都过了。

然后看到谋篇blog里有评论,把数据拿下来发现WA了。

数据是

2
0 0 1 1
1 0 2 1
就是有一条边贴着了,这个时候应该先加入新的边再删除,否则会算重。

另外,线段树不用清零哦。

 

 1 //#include<bits/stdc++.h>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 
 9 typedef int data_type;
10 const int N = 10000 + 10;
11 
12 data_type disc[N];
13 int disc_tot;
14 
15 int get_hash(data_type a[], int n, data_type x) {
16     return lower_bound(a, a + n, x) - a;
17 }
18 
19 struct Rect {
20     data_type x1, y1, x2, y2;
21     void input() {
22         scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
23         disc[disc_tot++] = y1, disc[disc_tot++] = y2;
24     }
25 } rect[N];
26 
27 struct Event {
28     int id, tp;
29     data_type key() const {
30         if(tp == 1) return rect[id].x1;
31         else return rect[id].x2;
32     }
33     bool operator < (const Event &rhs) const {
34         if(key() != rhs.key()) return key() < rhs.key();
35         return tp > rhs.tp; // 键值相同先加入再删除
36     }
37     Event() {}
38     Event(int id, int tp) : id(id), tp(tp) {}
39 } eve[N];
40 
41 struct SegmentTree {
42     data_type sum[N * 4];
43     int cnt[N * 4], lp[N * 4], rp[N * 4], num[N * 4];
44 #define lc s << 1
45 #define rc s << 1 | 1
46     void update(int s, int l, int r) {
47         if(cnt[s]) sum[s] = disc[r+1] - disc[l], lp[s] = rp[s] = num[s] = 1;
48         else if(l == r) sum[s] = 0, lp[s] = rp[s] = num[s] = 0;
49         else {
50             sum[s] = sum[lc] + sum[rc];
51             lp[s] = lp[lc], rp[s] = rp[rc];
52             num[s] = num[lc] + num[rc] - (rp[lc] && lp[rc]);
53         }
54     }
55     void modify(int s, int l, int r, int L, int R, int d) {
56         if(L <= l && r <= R) cnt[s] += d;
57         else {
58             int mid = (l + r) >> 1;
59             if(L <= mid) modify(lc, l, mid, L, R, d);
60             if(mid < R) modify(rc, mid + 1, r, L, R, d);
61         }
62         update(s, l, r);
63     }
64 #undef lc
65 #undef rc
66 } seg;
67 
68 bool solve() {
69     int n; if(scanf("%d", &n) == EOF) return 0;
70     disc_tot = 0;
71     for(int i = 0; i < n; i++) {
72         rect[i].input();
73         eve[i << 1] = Event(i, 1);
74         eve[i << 1 | 1] = Event(i, -1);
75     }
76     sort(disc, disc + disc_tot);
77     disc_tot = unique(disc, disc + disc_tot) - disc;
78     sort(eve, eve + (n << 1));
79     data_type res = 0, last = 0;
80     for(int i = 0; i < (n << 1); i++) {
81         const Event &e = eve[i];
82         if(i) res += (seg.num[1] << 1) * (e.key() - eve[i-1].key());
83         int l = get_hash(disc, disc_tot, rect[e.id].y1);
84         int r = get_hash(disc, disc_tot, rect[e.id].y2) - 1;
85         if(l <= r) seg.modify(1, 0, disc_tot - 2, l, r, e.tp);
86         res += abs(seg.sum[1] - last), last = seg.sum[1];
87     }
88     return printf("%d\n", res), 1;
89 }
90 
91 int main() {
92 #ifdef DEBUG
93     freopen("in.txt", "r", stdin);
94 #endif
95     while(solve());
96 
97     return 0;
98 }
View Code

 

posted @ 2016-06-14 16:14  Showson  阅读(229)  评论(0编辑  收藏  举报