矩形面积并(只覆盖一次的面积)的裸题。好久没写代码debug了我太久,太辛酸了。
#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define ll long long #define maxn 200005 #define y1 y111 int lf[maxn << 2], rf[maxn << 2]; int sum[maxn << 2]; int a[maxn]; int add[maxn << 2]; int mi[maxn << 2]; int ma[maxn << 2]; int n, nSize; void pushUp(int i) { mi[i] = min(mi[i << 1], mi[i << 1 | 1]); ma[i] = max(ma[i << 1], ma[i << 1 | 1]); } void pushDown(int i) { if (add[i] != 0){ if (lf[i] != rf[i]){ add[i << 1] += add[i]; add[i << 1 | 1] += add[i]; mi[i << 1] += add[i]; ma[i << 1] += add[i]; mi[i << 1 | 1] += add[i]; ma[i << 1 | 1] += add[i]; add[i] = 0; } } } void build(int i, int L, int R) { lf[i] = L; rf[i] = R; add[i] = mi[i] = ma[i] = 0; if (L == R){ sum[i] = a[L]; return; } int M = (L + R) >> 1; build(i << 1, L, M); build(i << 1 | 1, M + 1, R); sum[i] = sum[i << 1] + sum[i << 1 | 1]; } void upd(int i, int L, int R,int v) { if (L == lf[i] && R == rf[i]){ add[i] += v; mi[i] += v; ma[i] += v; return; } pushDown(i); int M = (lf[i] + rf[i]) >> 1; if (R <= M){ upd(i << 1, L, R,v); } else if (L > M){ upd(i << 1 | 1, L, R, v); } else{ upd(i << 1, L, M, v); upd(i << 1 | 1, M + 1, R, v); } pushUp(i); } ll query(int i) { if (ma[i] <= 0) return 0; if (mi[i] > 1) return 0; if (ma[i] == mi[i] && ma[i] == 1){ return sum[i]; } pushDown(i); return query(i << 1) + query(i << 1 | 1); } struct Node { ll x; ll bg, ed; int v; Node(ll xi, ll bgi, ll edi,int vi) :x(xi), bg(bgi), ed(edi),v(vi){} bool operator < (const Node &b)const{ return x == b.x ? v>b.v : x < b.x; } }; vector<Node> vec; vector<ll> dis; int main() { int T; cin >> T; int ca = 0; while (T--) { scanf("%d", &n); ll x1, x2, y1, y2; vec.clear(); vec.reserve(2 * n + 100); dis.clear(); for (int i = 0; i < n; ++i){ scanf("%I64d%I64d%I64d%I64d", &x1, &y1, &x2, &y2); vec.push_back(Node(x1, y1, y2,1)); vec.push_back(Node(x2, y1, y2,-1)); dis.push_back(y1); dis.push_back(y2); } sort(dis.begin(), dis.end()); nSize = unique(dis.begin(), dis.end()) - dis.begin(); for (int i = 1; i < nSize; ++i){ a[i] = dis[i] - dis[i - 1]; } for (int i = 0; i < vec.size(); ++i){ int lid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].bg) - dis.begin(); int rid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].ed) - dis.begin(); vec[i].bg = lid + 1; vec[i].ed = rid; } sort(vec.begin(), vec.end()); build(1, 1, nSize - 1); ll ans = 0; ll preLen = 0; ll prex = vec[0].x; for (int i = 0; i < vec.size(); ++i){ ll val = vec[i].x; while (i<vec.size()&&vec[i].x == val){ upd(1, vec[i].bg, vec[i].ed, vec[i].v); ++i; } --i; ans += preLen*(vec[i].x - prex); prex = vec[i].x; preLen = query(1); } printf("Case %d: %I64d ", ++ca, ans); } return 0; }