统计覆盖两次及以上的面积和。
思路:区间更新。建立线段树时,用cover域表示区间覆盖次数,once域表示区间被覆盖一次的长度,more域表示区间被覆盖两次及以上的长度。
用时250ms,rank11还是比较快的。
View Code
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define maxn 2005 7 struct node 8 { 9 double once,more; 10 int cover; 11 }setree[maxn<<2]; 12 struct 13 { 14 double l,r,h; 15 int c; 16 }mes[maxn]; 17 double xx[maxn]; 18 void quicksort(int l,int r) 19 { 20 if(l>=r) 21 return; 22 int i=l,j=r; 23 double c=mes[l].c,tl=mes[l].l,tr=mes[l].r; 24 double h=mes[l].h; 25 while(i<j){ 26 while(i<j&&h<=mes[j].h) 27 j--; 28 if(i<j){ 29 mes[i].l=mes[j].l; 30 mes[i].r=mes[j].r; 31 mes[i].c=mes[j].c; 32 mes[i].h=mes[j].h; 33 i++; 34 } 35 while(i<j&&h>mes[i].h) 36 i++; 37 if(i<j){ 38 mes[j].l=mes[i].l; 39 mes[j].r=mes[i].r; 40 mes[j].c=mes[i].c; 41 mes[j].h=mes[i].h; 42 j--; 43 } 44 } 45 mes[i].l=tl; 46 mes[i].r=tr; 47 mes[i].c=c; 48 mes[i].h=h; 49 quicksort(l,i-1); 50 quicksort(i+1,r); 51 } 52 void build(int l,int r,int rt) 53 { 54 setree[rt].once=0; 55 setree[rt].more=0; 56 setree[rt].cover=0; 57 if(l==r) 58 return; 59 int m=(l+r)>>1; 60 build(lson); 61 build(rson); 62 } 63 int binsearch(int l,int r,double num) 64 { 65 int m=(l+r)>>1; 66 if(xx[m]==num) 67 return m; 68 if(num<xx[m]) 69 return binsearch(l,m-1,num); 70 return binsearch(m+1,r,num); 71 } 72 void pushup(int rt,int l,int r) 73 { 74 if(r==l){ 75 if(setree[rt].cover==0) 76 setree[rt].once=setree[rt].more=0; 77 else if(setree[rt].cover==1){ 78 setree[rt].once=xx[r]-xx[l-1]; 79 setree[rt].more=0; 80 } 81 else{ 82 setree[rt].once=0; 83 setree[rt].more=xx[r]-xx[l-1]; 84 } 85 } 86 else{ 87 if(setree[rt].cover==0){ 88 setree[rt].once=setree[rt<<1].once+setree[rt<<1|1].once; 89 setree[rt].more=setree[rt<<1].more+setree[rt<<1|1].more; 90 } 91 else if(setree[rt].cover==1){ 92 setree[rt].more=setree[rt<<1].once+setree[rt<<1|1].once+setree[rt<<1].more+setree[rt<<1|1].more; 93 setree[rt].once=xx[r]-xx[l-1]-setree[rt].more; 94 } 95 else{ 96 setree[rt].more=xx[r]-xx[l-1]; 97 setree[rt].once=0; 98 } 99 } 100 } 101 void update(int l,int r,int rt,int L,int R,int c) 102 { 103 if(L<=l&&r<=R){ 104 setree[rt].cover+=c; 105 pushup(rt,l,r); 106 return; 107 } 108 int m=(l+r)>>1; 109 if(L<=m) 110 update(lson,L,R,c); 111 if(R>m) 112 update(rson,L,R,c); 113 pushup(rt,l,r); 114 } 115 int main() 116 { 117 int t; 118 scanf("%d",&t); 119 while(t--){ 120 int n,k=0; 121 scanf("%d",&n); 122 for(int i=0;i<n;i++){ 123 double a,b,c,d; 124 scanf("%lf%lf%lf%lf",&a,&b,&c,&d); 125 mes[k].l=a; 126 mes[k].r=c; 127 mes[k].h=b; 128 mes[k].c=1; 129 xx[k++]=a; 130 mes[k].l=a; 131 mes[k].r=c; 132 mes[k].h=d; 133 mes[k].c=-1; 134 xx[k++]=c; 135 } 136 sort(xx,xx+k); 137 quicksort(0,2*n-1); 138 int m=1; 139 double sum=0; 140 for(int i=1;i<k;i++) 141 if(xx[i]!=xx[i-1]) 142 xx[m++]=xx[i]; 143 k=m; 144 build(1,k-1,1); 145 for(int i=0;i<2*n;i++){ 146 int l=binsearch(0,k-1,mes[i].l); 147 int r=binsearch(0,k-1,mes[i].r); 148 update(1,k-1,1,l+1,r,mes[i].c); 149 sum+=setree[1].more*(mes[i+1].h-mes[i].h); 150 } 151 printf("%.2lf\n",sum); 152 } 153 return 0; 154 }