【HDOJ】 Picture (离散化+线段树)
7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
228
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <stack> #include <list> #include <algorithm> #include <map> #include <set> #define LL long long #define Pr pair<int,int> #define fread() freopen("in.in","r",stdin) #define fwrite() freopen("out.out","w",stdout) using namespace std; const int INF = 0x3f3f3f3f; const int msz = 10000; const int mod = 1e9+7; const double eps = 1e-8; struct Rectangle { int x,y1,y2; int ad; bool operator <(const struct Rectangle a)const { return x == a.x? ad > a.ad: x < a.x; } }; //存放矩形拆出的边 Rectangle rec[11111]; //线段树 如果为0表示当前区间为空白 如果为-1表示当前区间有空白也有线段,需要继续向下遍历 如果大于0表示当前区间的线段数量 int bit[666666]; //纵坐标离散化 int rey[11111]; //统计连续区间数量 int part; //纵坐标离散化后总编号 ans:答案 int tp,ans; //root:树根 l:区间左边界 r:区间右边界 ll:纵坐标左边界 rr:纵坐标右边界 d:增量 void update(int root,int l,int r,int ll,int rr,int d) { if(ll == rr) return; if(rey[l] == ll && rey[r+1] == rr && bit[root] != -1) { if((bit[root] == 0 && d == 1)||(bit[root]+d == 0 && d == -1)) ans += rr-ll; //printf("add:%d-%d\n",ll,rr); bit[root] += d; return; } int mid = (l+r)>>1; //如果当前区间不为-1 需要更新下去 if(bit[root] != -1) bit[root<<1] = bit[root<<1|1] = bit[root]; if(rey[mid+1] >= rr) update(root<<1,l,mid,ll,rr,d); else if(rey[mid+1] <= ll) update(root<<1|1,mid+1,r,ll,rr,d); else { update(root<<1,l,mid,ll,rey[mid+1],d); update(root<<1|1,mid+1,r,rey[mid+1],rr,d); } if(bit[root<<1] == bit[root<<1|1] && bit[root<<1] == 0) bit[root] = 0; else if(bit[root<<1] == bit[root<<1|1]) bit[root] = bit[root<<1]; else bit[root] = -1; } int lf,rf; void geth(int root,int l,int r) { if(bit[root] != -1) { if(root == 1 && bit[root]) part++; lf = bit[root]; rf = bit[root]; return; } int l1,r1,l2,r2; int mid = (l+r)>>1; geth(root<<1,l,mid); l1 = lf,r1 = rf; geth(root<<1|1,mid+1,r); l2 = lf,r2 = rf; if(root == 1 && l1 > 0) part++; if(r1 == 0 && l2 > 0) part++; lf = l1; rf = r2; } int main() { //fread(); //fwrite(); int n; while(~scanf("%d",&n)) { int tmp = 0; for(int i = 0; i < n; ++i) { scanf("%d%d%d%d",&rec[tmp].x,&rec[tmp].y1,&rec[tmp+1].x,&rec[tmp].y2); rec[tmp].ad = 1; rey[tmp] = rec[tmp].y1; tmp++; rec[tmp].ad = -1; rec[tmp].y1 = rec[tmp-1].y1; rec[tmp].y2 = rec[tmp-1].y2; rey[tmp] = rec[tmp].y2; tmp++; } sort(rey,rey+tmp); sort(rec,rec+tmp); int tp = 0; for(int i = 0; i < tmp; ++i) { if(i == 0 || rey[i] != rey[tp-1]) rey[tp++] = rey[i]; } ans = 0; // for(int i = 0; i < tp; ++i) // printf("%d ",rey[i]); // puts(""); memset(bit,0,sizeof(bit)); for(int i = 0; i < tmp; ++i) { //printf("time:%d %d %d\n",i,rec[i].y1,rec[i].y2); if(i != 0 && rec[i].x != rec[i-1].x) { part = 0; geth(1,0,tp-2); ans += part*2*(rec[i].x-rec[i-1].x); //printf("%d\n",ans); } update(1,0,tp-2,rec[i].y1,rec[i].y2,rec[i].ad); } printf("%d\n",ans); } return 0; }