hdu 3642 Get The Treasury

题意:给出n(n<=1000)个长方体,求重合三次及以上的体积和。

思路:枚举+扫描线+离散化。枚举z,求相应的覆盖三次及以上以上的面积和。

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 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 }
原文地址:https://www.cnblogs.com/kim888168/p/2986000.html