求解矩形面积交:
https://www.luogu.com.cn/problem/P5490
为了和区间匹配: 线段树的[l,r] 实际上代表了区间 [l,r + 1]
#include <cstdio> #include <iostream> #include <algorithm> #define ll long long #define ull unsigned long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a, b) (a>b?a:b) #define min(a, b) (a<b?a:b) const double eps = 1e-8; const int maxn = 1e6 + 10; const ll MOD = 1e9 + 7; const int mlog=20; int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; } using namespace std; ll x1,y1,x2,y2,X[maxn << 1]; struct ScanLine { ll l,r,h; int mark; bool operator < (const ScanLine &rhs) const { return h < rhs.h; } } line[maxn << 2]; struct segment_tree { int l,r,sum; ll len; }tree[maxn << 2]; void build(int l,int r,int nod) { tree[nod].l = l,tree[nod].r = r; tree[nod].len = 0; tree[nod].sum = 0; if (l == r) return ; int mid = (l + r) >> 1; build(l,mid,ls); build(mid+1,r,rs); } void push_up(int nod) { int l = tree[nod].l,r = tree[nod].r; if (tree[nod].sum) { tree[nod].len = X[r+1] - X[l]; } else tree[nod].len = tree[ls].len + tree[rs].len; } void modify(ll x,ll y,int f,int nod) { int l = tree[nod].l,r = tree[nod].r; if (X[r+1] <= x || X[l] >= y) return ; if (X[l] >= x && X[r+1] <= y) { tree[nod].sum += f; push_up(nod); return ; } modify(x,y,f,ls); modify(x,y,f,rs); push_up(nod); } int main() { int n; scanf("%d",&n); for (int i = 1;i <= n;i++) { scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); X[2 * i - 1] = x1,X[2 * i] = x2; line[2 * i - 1] = (ScanLine){x1,x2,y1,1}; line[2 * i] = (ScanLine){x1,x2,y2,-1}; } n <<= 1; sort(line + 1,line + 1 + n); sort(X + 1,X + 1 + n); int tot = unique(X + 1,X + n + 1) - X - 1; build(1,tot-1,1); ll ans = 0; for (int i = 1;i < n;i++) { modify(line[i].l,line[i].r,line[i].mark,1); ans += tree[1].len * (line[i+1].h - line[i].h); } printf("%lld ",ans); return 0; }
求矩形的周长:
https://www.luogu.com.cn/problem/P1856
#include <cstdio> #include <iostream> #include <algorithm> #define ll long long #define ull unsigned long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a, b) (a>b?a:b) #define min(a, b) (a<b?a:b) const double eps = 1e-8; const int maxn = 1e6 + 10; const ll MOD = 1e9 + 7; const int mlog=20; int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; } using namespace std; ll x1,y1,x2,y2,X[maxn << 1]; struct ScanLine { ll l,r,h; int mark; // 这里和面积交那里多了一个特判 bool operator < (const ScanLine &rhs) const { if (h == rhs.h) return mark > rhs.mark; return h < rhs.h; } } line[maxn << 2]; struct segment_tree { int l,r,sum,c; bool lc,rc; ll len; }tree[maxn << 2]; void build(int l,int r,int nod) { tree[nod].l = l,tree[nod].r = r; tree[nod].lc = tree[nod].rc = false; tree[nod].len = 0; tree[nod].sum = 0; if (l == r) return ; int mid = (l + r) >> 1; build(l,mid,ls); build(mid+1,r,rs); } void push_up(int nod) { int l = tree[nod].l,r = tree[nod].r; if (tree[nod].sum) { tree[nod].len = X[r+1] - X[l]; tree[nod].lc = tree[nod].rc = true; tree[nod].c = 1; } else { tree[nod].len = tree[ls].len + tree[rs].len; tree[nod].lc = tree[ls].lc,tree[nod].rc = tree[rs].rc; tree[nod].c = tree[ls].c + tree[rs].c; if (tree[ls].rc && tree[rs].lc) tree[nod].c -= 1; } } void modify(ll x,ll y,int f,int nod) { int l = tree[nod].l,r = tree[nod].r; if (X[r+1] <= x || X[l] >= y) return ; if (X[l] >= x && X[r+1] <= y) { tree[nod].sum += f; push_up(nod); return ; } modify(x,y,f,ls); modify(x,y,f,rs); push_up(nod); } int main() { int n; scanf("%d",&n); for (int i = 1;i <= n;i++) { scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2); X[2 * i - 1] = x1,X[2 * i] = x2; line[2 * i - 1] = (ScanLine){x1,x2,y1,1}; line[2 * i] = (ScanLine){x1,x2,y2,-1}; } n <<= 1; sort(line + 1,line + 1 + n); sort(X + 1,X + 1 + n); int tot = unique(X + 1,X + n + 1) - X - 1; build(1,tot-1,1); ll ans = 0; ll pre = 0; for (int i = 1;i < n;i++) { modify(line[i].l,line[i].r,line[i].mark,1); ans += abs(pre - tree[1].len); pre = tree[1].len; ans += 2 * tree[1].c * (line[i + 1].h - line[i].h); } ans += line[n].r - line[n].l; printf("%lld ",ans); return 0; }