洛谷P14426 [JOISC 2014] 稻草人 / Scarecrows 题解 CDQ分治
题目链接:https://www.luogu.com.cn/problem/P14426
解题思路参考自 ningyy大佬的这篇博客
受到博客启发,我按照自己的思路,开两棵线段树解决了本题。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
struct Point {
int x, y;
} a[maxn];
int n;
long long ans;
struct Segtree {
#define lson l, mid, u<<1
#define rson mid+1, r, u<<1|1
int t_max[maxn<<2], t_sum[maxn<<2];
void push_up(int u) {
t_max[u] = max(t_max[u<<1], t_max[u<<1|1]);
t_sum[u] = t_sum[u<<1] + t_sum[u<<1|1];
}
void add(int p, int val, int l, int r, int u) {
if (l == r) {
t_sum[u] += val;
t_max[u] += val;
return;
}
int mid = l + r >> 1;
(p <= mid) ? add(p, val, lson) : add(p, val, rson);
push_up(u);
}
int query_max(int L, int R, int l, int r, int u) {
if (L <= l && r <= R) return t_max[u];
int res = 0, mid = l + r >> 1;
if (L <= mid) res = max(res, query_max(L, R, lson));
if (R > mid) res = max(res, query_max(L, R, rson));
return res;
}
int query_sum(int L, int R, int l, int r, int u) {
if (L <= l && r <= R) return t_sum[u];
int res = 0, mid = l + r >> 1;
if (L <= mid) res += query_sum(L, R, lson);
if (R > mid) res += query_sum(L, R, rson);
return res;
}
void clean(int l, int r, int u) {
if (t_max[u] == 0 && t_sum[u] == 0) return;
t_max[u] = t_sum[u] = 0;
if (l == r) return;
int mid = l + r >>1;
clean(lson);
clean(rson);
}
} tsum, tmax;
void lsh() {
vector<int> v;
for (int i = 1; i <= n; i++) v.push_back(a[i].x);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 1; i <= n; i++)
a[i].x = lower_bound(v.begin(), v.end(), a[i].x) - v.begin() + 1;
v.clear();
for (int i = 1; i <= n; i++) v.push_back(a[i].y);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 1; i <= n; i++)
a[i].y = lower_bound(v.begin(), v.end(), a[i].y) - v.begin() + 1;
}
void cdq(int l, int r) {
if (l >= r)
return;
int mid = l + r >> 1;
cdq(l, mid);
cdq(mid+1, r);
sort(a+l, a+mid+1, [](auto a, auto b) {
return a.y < b.y;
});
sort(a+mid+1, a+r+1, [](auto a, auto b) {
return a.y < b.y;
});
tsum.clean(1, n, 1);
tmax.clean(1, n, 1);
stack<int> stk;
set<int> st;
int j = l, i = mid+1;
for (; i <= r; i++) {
for (; j <= mid && a[j].y <= a[i].y; j++) {
while (!stk.empty() && a[stk.top()].x < a[j].x) {
tsum.add(a[stk.top()].y, -1, 1, n, 1);
stk.pop();
}
stk.push(j);
tsum.add(a[j].y, 1, 1, n, 1);
}
int L = tmax.query_max(1, a[i].x, 1, n, 1);
int cnt = tsum.query_sum(L, a[i].y, 1, n, 1);
ans += cnt;
tmax.add(a[i].x, a[i].y, 1, n, 1);
st.insert(a[i].y);
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &a[i].x, &a[i].y);
lsh();
sort(a+1, a+n+1, [](auto a, auto b) {
return a.x < b.x;
});
cdq(1, n);
printf("%lld\n", ans);
return 0;
}
浙公网安备 33010602011771号