你需要实现一种数据结构支持以下操作:
- 区间加减 1
保证加减区间一一对应,且先加后减,序列中永远不出现负数。- 查询完整序列中 0 的个数
#include <cstdio>
#include <algorithm>
const int maxn = 1e5 + 10;
long long x[maxn * 2];
struct segmentTree
{
struct node
{
int l, r;
long long min, len, tag;
}
T[maxn * 2 * 4];
void downdata(int p)
{
T[p << 1].min += T[p].tag, T[p << 1].tag += T[p].tag;
T[(p << 1) | 1].min += T[p].tag, T[(p << 1) | 1].tag += T[p].tag;
T[p].tag = 0;
}
void updata(int p)
{
T[p].min = std::min(T[p << 1].min, T[(p << 1) | 1].min);
T[p].len = T[p << 1].len * (T[p << 1].min == T[p].min) + T[(p << 1) | 1].len * (T[(p << 1) | 1].min == T[p].min);
}
void build(int p, int l, int r)
{
T[p].l = l, T[p].r = r, T[p].tag = 0, T[p].min = 0, T[p].len = x[r + 1] - x[l];
if (l != r) build(p << 1, l, (l + r) >> 1), build((p << 1) | 1, ((l + r) >> 1) + 1, r), updata(p);
}
void add(int p, int l, int r, long long k)
{
if (r < T[p].l || T[p].r < l) return;
else if (l <= T[p].l && T[p].r <= r) T[p].tag += k, T[p].min += k;
else downdata(p), add(p << 1, l, r, k), add((p << 1) | 1, l, r, k), updata(p);
}
long long query(int p, int l, int r)
{
if (r < T[p].l || T[p].r < l) return 0;
else if (l <= T[p].l && T[p].r <= r) return T[p].min == 0 ? T[p].len : 0;
else return downdata(p), query(p << 1, l, r) + query((p << 1) | 1, l, r);
}
}
T;
struct node
{
long long x1, x2, y, k;
bool operator < (const node &that) const { return (*this).y < that.y; }
node(long long _x1 = 0, long long _x2 = 0, long long _y = 0, long long _k = 0) { x1 = _x1, x2 = _x2, y = _y, k = _k; }
}
a[maxn * 2];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
long long x1, y1, x2, y2;
scanf("%lld %lld %lld %lld", &x1, &y1, &x2, &y2);
a[2 * i - 1] = {x1, x2, y1, 1}, a[2 * i] = {x1, x2, y2, -1};
x[2 * i - 1] = x1, x[2 * i] = x2;
}
std::sort(a + 1, a + 2 * n + 1);
std::sort(x + 1, x + 2 * n + 1);
int len = std::unique(x + 1, x + 2 * n + 1) - (x + 1);
T.build(1, 1, len - 1);
long long ans = 0;
for (int i = 1; i <= 2 * n - 1; i++)
{
T.add(1, std::lower_bound(x + 1, x + len + 1, a[i].x1) - x, std::lower_bound(x + 1, x + len + 1, a[i].x2) - x - 1, a[i].k);
ans += (a[i + 1].y - a[i].y) * (x[len] - x[1] - T.query(1, 1, len - 1));
}
printf("%lld", ans);
return 0;
}
标签:struct,int,线段,long,maxn,扫描线,维护,void
From: https://www.cnblogs.com/wxr-blog/p/17968886