题意:给出n(n<=1000)个长方体,求重合三次及以上的体积和。
思路:枚举+扫描线+离散化。枚举z,求相应的覆盖三次及以上以上的面积和。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 op 8 { 9 int l,r,y,cnt; 10 }mes[maxn]; 11 struct opp 12 { 13 int x1,x2,y1,y2,z1,z2; 14 }rec[maxn/2]; 15 struct node 16 { 17 __int64 once,twice,more; 18 int cnt; 19 }setree[maxn<<2]; 20 int z[maxn],y[maxn]; 21 int sorted[maxn]; 22 __int64 ans; 23 bool cmp(struct op a,struct op b) 24 { 25 return a.y<b.y; 26 } 27 void build(int l,int r,int rt) 28 { 29 setree[rt].cnt=0; 30 setree[rt].once=setree[rt].twice=setree[rt].more=0; 31 if(l==r) 32 return; 33 int m=(l+r)>>1; 34 build(lson); 35 build(rson); 36 } 37 int binsearch(int l,int r,int num) 38 { 39 int m=(l+r)>>1; 40 if(sorted[m]==num) 41 return m; 42 if(num<sorted[m]) 43 return binsearch(l,m-1,num); 44 return binsearch(m+1,r,num); 45 } 46 void pushup(int rt,int l,int r) 47 { 48 if(setree[rt].cnt==0){ 49 if(l==r) 50 setree[rt].once=setree[rt].twice=setree[rt].more=0; 51 else{ 52 setree[rt].once=setree[rt<<1].once+setree[rt<<1|1].once; 53 setree[rt].twice=setree[rt<<1].twice+setree[rt<<1|1].twice; 54 setree[rt].more=setree[rt<<1].more+setree[rt<<1|1].more; 55 } 56 } 57 else if(setree[rt].cnt==1){ 58 if(l==r){ 59 setree[rt].once=sorted[r]-sorted[l-1]; 60 setree[rt].twice=0; 61 setree[rt].more=0; 62 } 63 else{ 64 setree[rt].more=setree[rt<<1].more+setree[rt<<1|1].more+setree[rt<<1].twice+setree[rt<<1|1].twice; 65 setree[rt].twice=setree[rt<<1].once+setree[rt<<1|1].once; 66 setree[rt].once=sorted[r]-sorted[l-1]-setree[rt].twice-setree[rt].more; 67 } 68 } 69 else if(setree[rt].cnt==2){ 70 if(l==r){ 71 setree[rt].once=0; 72 setree[rt].twice=sorted[r]-sorted[l-1]; 73 setree[rt].more=0; 74 } 75 else{ 76 setree[rt].more=setree[rt<<1].more+setree[rt<<1|1].more+setree[rt<<1].twice+setree[rt<<1|1].twice+setree[rt<<1].once+setree[rt<<1|1].once; 77 setree[rt].once=0; 78 setree[rt].twice=sorted[r]-sorted[l-1]-setree[rt].once-setree[rt].more; 79 } 80 } 81 else{ 82 setree[rt].once=0; 83 setree[rt].twice=0; 84 setree[rt].more=sorted[r]-sorted[l-1]; 85 } 86 } 87 void update(int l,int r,int rt,int L,int R,int c) 88 { 89 if(L<=l&&r<=R){ 90 setree[rt].cnt+=c; 91 pushup(rt,l,r); 92 return; 93 } 94 int m=(l+r)>>1; 95 if(L<=m) 96 update(lson,L,R,c); 97 if(R>m) 98 update(rson,L,R,c); 99 pushup(rt,l,r); 100 } 101 __int64 solve1(int n,int k) 102 { 103 __int64 res=0; 104 build(1,k,1); 105 for(int i=0;i<n;i++){ 106 int l=binsearch(0,k-1,mes[i].l); 107 int r=binsearch(0,k-1,mes[i].r); 108 update(1,k,1,l+1,r,mes[i].cnt); 109 res+=(long long)setree[1].more*(mes[i+1].y-mes[i].y); 110 } 111 return res; 112 } 113 void solve(int n,int k) 114 { 115 ans=0; 116 for(int i=0;i<k;i++){ 117 int k1=0; 118 for(int j=0;j<n;j++){ 119 if(rec[j].z1<=z[i]&&rec[j].z2>z[i]){ 120 mes[2*k1].l=rec[j].x1;mes[2*k1].r=rec[j].x2;mes[2*k1].y=rec[j].y1;mes[2*k1].cnt=1; 121 mes[2*k1+1].l=rec[j].x1;mes[2*k1+1].r=rec[j].x2;mes[2*k1+1].y=rec[j].y2;mes[2*k1+1].cnt=-1; 122 sorted[2*k1]=rec[j].x1; 123 sorted[2*k1+1]=rec[j].x2; 124 k1++; 125 } 126 } 127 sort(sorted,sorted+2*k1); 128 sort(mes,mes+2*k1,cmp); 129 int k2=1; 130 for(int j=1;j<2*k1;j++) 131 if(sorted[j]!=sorted[j-1]) 132 sorted[k2++]=sorted[j]; 133 ans+=(__int64)(z[i+1]-z[i])*solve1(2*k1,k2); 134 } 135 } 136 int main() 137 { 138 int cas=1,t; 139 scanf("%d",&t); 140 while(t--){ 141 int n; 142 scanf("%d",&n); 143 for(int i=0;i<n;i++){ 144 scanf("%d%d%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].z1,&rec[i].x2,&rec[i].y2,&rec[i].z2); 145 z[2*i]=rec[i].z1; 146 z[2*i+1]=rec[i].z2; 147 } 148 sort(z,z+2*n); 149 int k=1; 150 for(int i=1;i<2*n;i++) 151 if(z[i]!=z[i-1]) 152 z[k++]=z[i]; 153 solve(n,k); 154 printf("Case %d: ",cas++); 155 printf("%I64d\n",ans); 156 } 157 return 0; 158 }