https://www.acmicpc.net/problem/3392
코드는 다음 블로그의 코드를 많이 참조했습니다.
https://jason9319.tistory.com/58
일반적인 세그트리의 형태를 따르지 않고, 세그먼트트리의 구조를 이용하여 풀 수 있는 문제.
<문제설명>
좌표가 최대 30000인 2차원 평면 상에 최대 1e4개의 직사각형이 주어질 때, 직사각형들이 이루는 영역의 크기를 구하라
<풀이>
x좌표가 증가하는 순서대로 막대기들을 볼 때, "이전 x좌표와의 차 dx"와 "y좌표들의 psum이 1이상인 곳의 개수"를 곱해나가면 된다.
지금 막대기가 [y1,y2)일 떄 이 막대기가 시작 막대기인 경우 해당구간을 모두 +1, 끝 막대기인 경우 해당구간을 모두 -1해주며 배열을 유지해 나간다고 생각해야 한다.
이걸 lazy propagation을 사용해서 구현하려고 하면 다소 복잡하다. 실제로 할 수 있는지도 모르겠다.
세그먼트트리의 구조를 이용해서, 업데이트할 구간에 [ns,ne]가 들어가면, 그 구간 안의 모든 요소들을 update해야한다는 의미이다. 이것을 세그먼트트리의 second에 유지해두둔다. 업데이트할 구간에 [ns,ne]가 들어가지 않는다면 왼쪽,오른쪽 자식노드에 대해서 계속 업데이트를 해 나간다.
재귀의 맨 끝에 도달하여 반환하기 시작하면서 second값과 왼쪽,오른쪽 자식노드의 first(실제 값)을 기반으로 현재 노드의 first(실제 값)을 갱신해 나가면 된다.
현재 노드의 second값이 1이상이라면 그 구간에 포함되는 모든 요소들의 개수를 first 값으로 취한다.
현재 노드의 second값이 0이하라면 왼쪽,오른쪽 자식노드의 first값을 더해준다.
<코드>
const int MAX = 2e4 + 4;
const int SMAX = (1 << 18);
ll n,px;
vector<T> a;
P seg[SMAX];
void update(int s, int e, int x, int i = 1, int ns = 0, int ne = SMAX / 2 - 1) {
if (e < ns || ne < s) return;
if (s <= ns && ne <= e) {
seg[i].second += x;
}
else {
int md = (ns + ne) / 2;
update(s, e, x, i * 2, ns, md);
update(s, e, x, i * 2 + 1, md + 1, ne);
}
if (seg[i].second > 0) seg[i].first = ne - ns + 1;
else {
if (ns == ne) seg[i].first = 0;
else seg[i].first = seg[i * 2].first + seg[i * 2 + 1].first;
}
}
int main() {
FAST; cin >> n;
for (int i = 0,x1,y1,x2,y2; i < n; i++) {
cin >> x1 >> y1 >> x2 >> y2;
a.push_back({ x1,y1,y2 - y1 });
a.push_back({ -x2,y1,y2 - y1 });
}
sort(a.begin(), a.end(), [](T t1, T t2) {
return abs(get<0>(t1)) < abs(get<0>(t2));
});
ll ans = 0;
for (ll i = 0,x,y,d; i < a.size(); i++) {
tie(x, y, d) = a[i];
ans += seg[1].first * (abs(x)-px);
update(y, y + d-1, (x >= 0 ? 1 : -1));
px = abs(x);
}
cout << ans << '\n';
}
'알고리즘 > 백준 & swacademy' 카테고리의 다른 글
BOJ 7469 - K번째 수 ( 머지소트트리, pst ) (0) | 2020.06.10 |
---|---|
BOJ 17306 - 전쟁 중의 삶 (트라이, 완전이진트리) (0) | 2020.06.10 |
BOJ 15899 - 트리의 색깔 (ett, 머지소트트리) (0) | 2020.06.02 |
BOJ 2912 - 백설공주와 난쟁이 (머지소트트리, 구간 과반수) (0) | 2020.06.02 |
BOJ 15977 - 조화로운 행렬 (분할정복, 세그트리) (0) | 2020.05.30 |