标签:script key first ram read contains 线段树 技术分享 sum
Description
Input
Output
Sample Input
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
Sample Output
228
Source
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstdio> 5 const int N = 10000 + 11 ; 6 using namespace std; 7 int n ,li[N] , tot; 8 struct id 9 { 10 int x,y1,x2,y2,flag; 11 } line[N]; 12 struct a_seg_tree 13 { 14 struct a_tree 15 { 16 int l,r,cnt,qucnt,len,lenall,seg,mid; 17 bool rbd,lbd ; 18 } tree[N<<2]; 19 void build(int l,int r,int num) 20 { 21 tree[num].l = l , tree[num].r = r; 22 tree[num].lenall = tree[num].cnt = tree[num].seg = 0; 23 int mid = l + ( (r - l )>>1),ii = num << 1 ; 24 tree[num].len = li[r] - li[l]; 25 tree[num].mid = mid; 26 if(r - l > 1) 27 { 28 build(l,mid,ii); 29 build(mid,r,ii+1); 30 } 31 } 32 void Update(int num) 33 { 34 if(tree[num].cnt > 0) 35 { 36 tree[num].lenall = tree[num].len; 37 tree[num].seg = 1; 38 tree[num].lbd = tree[num].rbd = true ; 39 } 40 else if(tree[num].r-tree[num].l>1) 41 { 42 int ii = num << 1; 43 tree[num].lenall = tree[ii].lenall + tree[ii+1].lenall; 44 tree[num].lbd = tree[ii].lbd; 45 tree[num].rbd = tree[ii+1].rbd; 46 tree[num].seg = tree[ii].seg + tree[ii+1].seg - (tree[ii].rbd & tree[ii+1].lbd); 47 } 48 else 49 { 50 tree[num].lenall = tree[num].seg = 0; 51 tree[num].lbd = tree[num].rbd = false; 52 } 53 54 } 55 void Insert(int l,int r,int num) 56 { 57 if(l == tree[num].l && r == tree[num].r) ++tree[num].cnt; 58 else 59 { 60 int mid = tree[num].mid,ii = num << 1; 61 if(r <= mid) Insert(l,r,ii); 62 else if(l >= mid) Insert(l,r,ii+1); 63 else Insert(l,mid,ii),Insert(mid,r,ii+1); 64 } 65 Update(num); 66 } 67 void Delete(int l,int r,int num) 68 { 69 if(l == tree[num].l && r == tree[num].r)--tree[num].cnt; 70 else 71 { 72 int mid = tree[num].mid,ii = num << 1; 73 if(r <= mid)Delete(l,r,ii); 74 else if(l>=mid)Delete(l,r,ii+1); 75 else Delete(l,mid,ii),Delete(mid,r,ii+1); 76 } 77 Update(num); 78 } 79 }seg_tree; 80 81 int cmp(id a,id b) 82 { 83 if(a.x == b.x)return a.flag > b.flag; 84 return a.x < b.x; 85 } 86 87 88 void Init() 89 { 90 scanf("%d",&n); 91 int x1,y1,x2,y2,i= 0; 92 while(n--) 93 { 94 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 95 line[++i].x=x1,line[i].y1=y1,line[i].y2=y2,line[i].flag=1;li[i]=y1; 96 line[++i].x=x2,line[i].y1=y1,line[i].y2=y2,line[i].flag=-1;li[i]=y2; 97 } 98 sort(li+1,li+1+i); n = i ; 99 sort(line+1,line+1+i,cmp); 100 tot = 1 ; 101 for(int j = 2; j <= i ; ++j ) 102 if(li[j] != li[tot])li[++tot] = li[j]; 103 } 104 105 int binary_search( int sum ) 106 { 107 int l = 1 , r = tot; 108 while(l <= r) 109 { 110 int mid = l + ((r-l)>>1); 111 if(li[mid] == sum)return mid; 112 if(sum<li[mid])r = mid - 1; 113 else l = mid + 1; 114 } 115 return -1; 116 } 117 118 void Solve() 119 { 120 seg_tree.build(1,tot,1); 121 int ans = 0 , pre = 0 ; 122 for(int i = 1; i < n;++i) 123 { 124 int y1 = binary_search(line[i].y1) , y2 = binary_search(line[i].y2) ; 125 if(line[i].flag == 1 ) 126 seg_tree.Insert(y1,y2,1) ; 127 else 128 seg_tree.Delete(y1,y2,1); 129 ans += seg_tree.tree[1].seg * (line[i+1].x-line[i].x) << 1 ; 130 ans += abs(seg_tree.tree[1].lenall-pre); 131 132 pre = seg_tree.tree[1].lenall; 133 } 134 seg_tree.Delete(binary_search(line[n].y1),binary_search(line[n].y2),1); 135 ans += abs(seg_tree.tree[1].lenall - pre) ; 136 printf("%d\n",ans); 137 } 138 139 int main() 140 { 141 // freopen("picture.in","r",stdin); 142 // freopen("picture.out","w",stdout); 143 Init(); 144 Solve(); 145 fclose(stdin); 146 fclose(stdout); 147 return 0 ; 148 }
标签:script key first ram read contains 线段树 技术分享 sum
原文地址:http://www.cnblogs.com/Ateisti/p/6064349.html