hdu 3642 长方体体积交....线段树
解题思路:
一开始看题完全没思路,本来以为要建一个三维的线段树,以为暂时不能够动了,但是之后忍不住了,看了解题报告,原来是枚举z轴上面的值就可以了,这样猥琐过都可以。。。看来还是自己观察数据不够到位。。。
然后针对每一层z轴,建立一个线段树,对覆盖三次以上的面积求和,然后再求体积。。。
View Code
1 #include<iostream> 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 #include<string.h> 6 using std::sort; 7 using std::unique; 8 const int N = 1111; 9 struct node 10 { 11 int x1,y1,z1; 12 int x2,y2,z2; 13 }Vo[N]; 14 struct line 15 { 16 int y,x1,x2; 17 int s; 18 bool operator<(const line &tmp)const 19 { 20 return y<tmp.y; 21 } 22 }Li[N<<2]; 23 int topl; 24 int X[N<<2],Z[N<<2],topx,topz; 25 int cover[N<<2]; 26 __int64 sum1[N<<2],sum2[N<<2],sum3[N<<2]; 27 int Fin(double k,int len) 28 { 29 int l=0,r=len; 30 while(l<r) 31 { 32 int m=(l+r)>>1; 33 if(X[m]==k)return m; 34 if(X[m]>k)r=m-1; 35 else l=m+1; 36 } 37 return l; 38 } 39 void PushUp(int t,int l,int r) 40 { 41 if(cover[t]>=3) 42 { 43 sum3[t]=sum2[t]=sum1[t]=(__int64)X[r+1]-X[l]; 44 } 45 else 46 if(cover[t]==2) 47 { 48 49 sum2[t]=sum1[t]=(__int64)X[r+1]-X[l]; 50 if(l==r)sum3[t]=0; 51 else 52 sum3[t]=sum1[t<<1]+sum1[t<<1|1]; 53 } 54 else 55 if(cover[t]==1) 56 { 57 sum1[t]=(__int64)X[r+1]-X[l]; 58 if(l==r)sum2[t]=sum3[t]=0; 59 else 60 { 61 sum2[t]=sum1[t<<1]+sum1[t<<1|1]; 62 sum3[t]=sum2[t<<1]+sum2[t<<1|1]; 63 } 64 } 65 else 66 { 67 if(l==r)sum1[t]=sum2[t]=sum3[t]=0; 68 else 69 { 70 sum1[t]=sum1[t<<1]+sum1[t<<1|1]; 71 sum2[t]=sum2[t<<1]+sum2[t<<1|1]; 72 sum3[t]=sum3[t<<1]+sum3[t<<1|1]; 73 } 74 } 75 } 76 void update(int t,int l,int r,int L,int R,int val) 77 { 78 if(L<=l&&r<=R) 79 { 80 cover[t]+=val; 81 PushUp(t,l,r); 82 return ; 83 } 84 int m=(r+l)>>1; 85 if(L<=m)update(t<<1,l,m,L,R,val); 86 if(R>m)update(t<<1|1,m+1,r,L,R,val); 87 PushUp(t,l,r); 88 } 89 int main() 90 { 91 int t,n,T=0; 92 scanf("%d",&t); 93 while(t--) 94 { 95 scanf("%d",&n); 96 topz=0; 97 for(int i=0;i<n;i++) 98 { 99 scanf("%d%d%d%d%d%d",&Vo[i].x1,&Vo[i].y1,&Vo[i].z1,&Vo[i].x2,&Vo[i].y2,&Vo[i].z2); 100 Z[topz++]=Vo[i].z1; 101 Z[topz++]=Vo[i].z2; 102 } 103 sort(Z,Z+topz); 104 topz=unique(Z,Z+topz)-Z; 105 __int64 ans=0,ret; 106 for(int i=0;i<topz-1;i++) 107 { 108 topl=topx=0; 109 for(int j=0;j<n;j++) 110 { 111 if(Vo[j].z1<=Z[i]&&Vo[j].z2>Z[i]) 112 { 113 X[topx++]=Vo[j].x1; 114 X[topx++]=Vo[j].x2; 115 Li[topl].y=Vo[j].y1;Li[topl].x1=Vo[j].x1;Li[topl].x2=Vo[j].x2;Li[topl].s=1;topl++; 116 Li[topl].y=Vo[j].y2;Li[topl].x1=Vo[j].x1;Li[topl].x2=Vo[j].x2;Li[topl].s=-1;topl++; 117 } 118 } 119 sort(X,X+topx); 120 sort(Li,Li+topl); 121 topx=unique(X,X+topx)-X; 122 memset(sum1,0,sizeof(sum1)); 123 memset(sum2,0,sizeof(sum2)); 124 memset(sum3,0,sizeof(sum3)); 125 memset(cover,0,sizeof(cover)); 126 ret=0; 127 for(int k=0;k<topl-1;k++) 128 { 129 int l=Fin(Li[k].x1,topx-1); 130 int r=Fin(Li[k].x2,topx-1)-1; 131 if(l<=r)update(1,0,topx-1,l,r,Li[k].s); 132 ret+=sum3[1]*(__int64)(Li[k+1].y-Li[k].y); 133 } 134 ans+=ret*(__int64)(Z[i+1]-Z[i]); 135 } 136 printf("Case %d: %I64d\n",++T,ans); 137 } 138 return 0; 139 }