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 }

 

posted @ 2012-11-05 18:32  诺小J  阅读(207)  评论(0编辑  收藏  举报