2014-09-25 01:41:49
思路:基本思路和p1151差不多,首先把线段分成平行于x轴和平行于y轴的两组,分别考虑。注意把每个点的x,y坐标加10001,因为线段树节点下标不能为负和0,(当然用离散化做就不用这样处理了),每加进来一条线段,就对相应的线段cover值加1,然后求出当前已经被覆盖的区间的总长度L,然后:把这次求出的 L 和上一次求出的 L’ 作差取绝对值,就得到了因为加入当前线段而新增的周长。就这样逐个计算累加,即得答案。
自己YY水过。。。QAQ
1 /************************************************************************* 2 > File Name: p1177.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 24 Sep 2014 10:39:20 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 typedef long long ll; 18 const int INF = 1 << 29; 19 const int maxn = 10010; 20 const int RA = 20000; 21 22 struct Edge{ 23 int st,p1,p2,flag; 24 inline friend bool operator < (Edge a,Edge b){ 25 return a.st < b.st; 26 } 27 }ey[maxn],ex[maxn]; 28 29 struct node{ 30 int l,r; 31 int cover,len; 32 }a[maxn << 4]; 33 34 int n; 35 int y[maxn],x[maxn]; 36 37 void Build_tree(int pos,int l,int r){ 38 a[pos].l = l; 39 a[pos].r = r; 40 a[pos].cover = a[pos].len = 0; 41 if(l + 1 == r) 42 return; 43 int mid = l + (r - l) / 2; 44 Build_tree(pos << 1,l,mid); 45 Build_tree(pos << 1 | 1,mid,r); 46 } 47 48 void Cal_len(int pos){ 49 if(a[pos].cover >= 1) 50 a[pos].len = a[pos].r - a[pos].l; 51 else if(a[pos].l + 1 == a[pos].r) 52 a[pos].len = 0; 53 else 54 a[pos].len = a[pos << 1].len + a[pos << 1 | 1].len; 55 } 56 57 void Update(int pos,int l,int r,Edge t){ 58 if(a[pos].l == t.p1 && a[pos].r == t.p2){ 59 a[pos].cover += t.flag; 60 Cal_len(pos); 61 return; 62 } 63 int mid = l + (r - l) / 2; 64 if(t.p2 <= mid) Update(pos << 1,l,mid,t); 65 else if(t.p1 >= mid) Update(pos << 1 | 1,mid,r,t); 66 else{ 67 Edge tmp = t; 68 tmp.p2 = mid; 69 Update(pos << 1,l,mid,tmp); 70 tmp.p2 = t.p2; 71 tmp.p1 = mid; 72 Update(pos << 1 | 1,mid,r,tmp); 73 } 74 Cal_len(pos); 75 } 76 77 int main(){ 78 //freopen("in","r",stdin); 79 int x1,y1,x2,y2,c = 0; 80 scanf("%d",&n); 81 for(int i = 1; i <= n; ++i){ 82 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 83 x1 += 10001; 84 y1 += 10001; 85 x2 += 10001; 86 y2 += 10001; 87 88 ey[++c].st = x1; 89 ey[c].p1 = y1; 90 ey[c].p2 = y2; 91 ey[c].flag = 1; 92 y[c] = y1; 93 ex[c].st = y1; 94 ex[c].p1 = x1; 95 ex[c].p2 = x2; 96 ex[c].flag = 1; 97 x[c] = x1; 98 99 ey[++c].st = x2; 100 ey[c].p1 = y1; 101 ey[c].p2 = y2; 102 ey[c].flag = -1; 103 y[c] = y2; 104 ex[c].st = y2; 105 ex[c].p1 = x1; 106 ex[c].p2 = x2; 107 ex[c].flag = -1; 108 x[c] = x2; 109 } 110 sort(ey + 1,ey + c + 1); 111 sort(ex + 1,ex + c + 1); 112 sort(y + 1,y + c + 1); 113 sort(x + 1,x + c + 1); 114 int wide = 0,high = 0,pre = 0; 115 Build_tree(1,1,RA); 116 for(int i = 1; i <= c; ++i){ 117 Update(1,1,RA,ey[i]); 118 wide += abs(a[1].len - pre); 119 pre = a[1].len; 120 } 121 Build_tree(1,1,RA); 122 pre = 0; 123 for(int i = 1; i <= c; ++i){ 124 Update(1,1,RA,ex[i]); 125 high += abs(a[1].len - pre); 126 pre = a[1].len; 127 } 128 printf("%d\n",wide + high); 129 return 0; 130 }