【题目链接】
【算法】
线段树扫描线求周长并
【代码】
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 5010 int i,L,R,l1,l2,ans,last,n,xa,xb,ya,yb; int x[MAXN*2]; struct info { int l,r,h,opt; } y[MAXN*2]; struct Node { int l,r,sum,cnt,c; bool lc,rc; } Tree[MAXN*10]; bool cmp(info a,info b) { return a.h > b.h; } template <typename T> inline void read(T &x) { int f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } template <typename T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> inline void writeln(T x) { write(x); puts(""); } inline void build(int index,int l,int r) { int mid; Tree[index].l = l; Tree[index].r = r; Tree[index].c = Tree[index].sum = Tree[index].cnt = 0; Tree[index].lc = Tree[index].rc = false; if (l == r) return; mid = (l + r) >> 1; build(index<<1,l,mid); build(index<<1|1,mid+1,r); } inline void push_up(int index) { if (Tree[index].c > 0) { Tree[index].sum = x[Tree[index].r+1] - x[Tree[index].l]; Tree[index].cnt = 1; Tree[index].lc = Tree[index].rc = true; } else if (Tree[index].l == Tree[index].r) { Tree[index].sum = Tree[index].cnt = 0; Tree[index].lc = Tree[index].rc = false; } else { Tree[index].lc = Tree[index<<1].lc; Tree[index].rc = Tree[index<<1|1].rc; Tree[index].sum = Tree[index<<1].sum + Tree[index<<1|1].sum; Tree[index].cnt = Tree[index<<1].cnt + Tree[index<<1|1].cnt; if (Tree[index<<1].rc && Tree[index<<1|1].lc) Tree[index].cnt--; } } inline void update(int index,int l,int r,int val) { int mid; if (Tree[index].l == l && Tree[index].r == r) { Tree[index].c += val; push_up(index); return; } mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) update(index<<1,l,r,val); else if (mid + 1 <= l) update(index<<1|1,l,r,val); else { update(index<<1,l,mid,val); update(index<<1|1,mid+1,r,val); } push_up(index); } int main() { scanf("%d",&n); l1 = l2 = 0; for (i = 1; i <= n; i++) { read(xa); read(ya); read(xb); read(yb); x[++l1] = xa; x[++l1] = xb; y[++l2] = (info){xa,xb,ya,-1}; y[++l2] = (info){xa,xb,yb,1}; } l1 = unique(x+1,x+l1+1) - x; sort(x+1,x+l1+1); build(1,1,l1-1); sort(y+1,y+l2+1,cmp); ans = last = 0; for (i = 1; i < l2; i++) { L = lower_bound(x+1,x+l1+1,y[i].l) - x; R = lower_bound(x+1,x+l1+1,y[i].r) - x - 1; update(1,L,R,y[i].opt); ans += Tree[1].cnt * 2 * (y[i].h - y[i+1].h); ans += abs(Tree[1].sum - last); last = Tree[1].sum; } L = lower_bound(x+1,x+l1+1,y[l2].l) - x; R = lower_bound(x+1,x+l1+1,y[l2].r) - x - 1; update(1,L,R,y[l2].opt); ans += abs(Tree[1].sum - last); writeln(ans); return 0; }