hdu3642Get The Treasury
刚开始看n挺小,以为是二维的线段树,想了一会也没想到怎么解,之后看到z值非常小,想到可以直接枚举z,确定一个坐标,然后把三维转化为二维,把体积转化为面。
枚举z从-500到500,然后用面积并的解法求出单位z坐标上满足题意的面积。
把1写成了L,查错查了好久。其余还好,1A。
求覆盖超过两次的面积,up更新上的写法如下:
void up(int w,int l,int r) { if(fs[w]>2) { s[w][0] = s[w][1] = s[w][2] = val[r+1] - val[l]; } else if(fs[w]>1) { s[w][0] = s[w][1] = val[r+1]-val[l]; if(l==r) s[w][2] = 0; else s[w][2] = s[w<<1][0]+s[w<<1|1][0]; } else if(fs[w]) { s[w][0] = val[r+1]-val[l]; if(l==r) s[w][1] = s[w][2] = 0; else { s[w][2] = s[w<<1][1]+s[w<<1|1][1]; s[w][1] =s[w<<1][0]+s[w<<1|1][0]; } } else { if(l==r) s[w][0] = s[w][1] = s[w][2] = 0; else { s[w][0] = s[w<<1][0]+s[w<<1|1][0]; s[w][1] = s[w<<1][1]+s[w<<1|1][1]; s[w][2] = s[w<<1][2]+s[w<<1|1][2]; } } }
代码:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<map> 11 using namespace std; 12 #define N 2010 13 #define LL __int64 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 map<int,int>f; 19 struct node 20 { 21 int x1,x2,y,f; 22 int z1,z2; 23 node(){} 24 node(int x1,int x2,int y,int f,int z1,int z2):x1(x1),x2(x2),y(y),f(f),z1(z1),z2(z2){} 25 bool operator < (const node &S) const 26 { 27 return y<S.y; 28 } 29 }p[N],q[N]; 30 int a[N],val[N]; 31 int s[N<<2][3],fs[N<<2]; 32 void up(int w,int l,int r) 33 { 34 if(fs[w]>2) 35 { 36 s[w][0] = s[w][1] = s[w][2] = val[r+1] - val[l]; 37 } 38 else if(fs[w]>1) 39 { 40 s[w][0] = s[w][1] = val[r+1]-val[l]; 41 if(l==r) 42 s[w][2] = 0; 43 else s[w][2] = s[w<<1][0]+s[w<<1|1][0]; 44 } 45 else if(fs[w]) 46 { 47 s[w][0] = val[r+1]-val[l]; 48 if(l==r) 49 s[w][1] = s[w][2] = 0; 50 else 51 { 52 s[w][2] = s[w<<1][1]+s[w<<1|1][1]; 53 s[w][1] =s[w<<1][0]+s[w<<1|1][0]; 54 } 55 } 56 else 57 { 58 if(l==r) 59 s[w][0] = s[w][1] = s[w][2] = 0; 60 else 61 { 62 s[w][0] = s[w<<1][0]+s[w<<1|1][0]; 63 s[w][1] = s[w<<1][1]+s[w<<1|1][1]; 64 s[w][2] = s[w<<1][2]+s[w<<1|1][2]; 65 } 66 } 67 } 68 void build(int l,int r,int w) 69 { 70 s[w][0] = s[w][1] = s[w][2] = 0; 71 fs[w] = 0; 72 if(l==r) 73 return ; 74 int m = (l+r)>>1; 75 build(l,m,w<<1); 76 build(m+1,r,w<<1|1); 77 up(w,l,r); 78 } 79 void update(int a,int b,int d,int l,int r,int w) 80 { 81 // cout<<l<<" "<<r<<" "<<w<<endl; 82 if(a<=l&&b>=r) 83 { 84 fs[w]+=d; 85 //cout<<l<<" "<<r<<" "<<fs[w]<<" "<<w<<endl; 86 up(w,l,r); 87 return ; 88 } 89 int m = (l+r)>>1; 90 if(a<=m) update(a,b,d,l,m,w<<1); 91 if(b>m) update(a,b,d,m+1,r,w<<1|1); 92 up(w,l,r); 93 } 94 int main() 95 { 96 int n,i,j; 97 int t,kk=0; 98 cin>>t; 99 while(t--) 100 { 101 scanf("%d",&n); 102 f.clear(); 103 int g = 0; 104 for(i = 1 ;i <= n; i++) 105 { 106 int x1,x2,y1,y2,z1,z2; 107 scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2); 108 p[++g] = node(x1,x2,y1,1,z1,z2); 109 a[g] = x1; 110 p[++g] = node(x1,x2,y2,-1,z1,z2); 111 a[g] = x2; 112 } 113 sort(a+1,a+g+1); 114 sort(p+1,p+g+1); 115 int o = 0; 116 f[a[1]] = ++o; 117 val[1] = a[1]; 118 for(i = 2; i <= g; i++) 119 if(a[i]!=a[i-1]) 120 { 121 f[a[i]] = ++o; 122 val[o] = a[i]; 123 } 124 LL ans = 0; 125 for(i = -500 ; i < 500 ; i++) 126 { 127 int e = 0; 128 build(1,o-1,1); 129 for(j = 1; j <= g ;j++) 130 { 131 if(p[j].z1>i||p[j].z1>i+1||i>p[j].z2||p[j].z2<i+1) 132 continue; 133 q[++e] = p[j]; 134 } 135 for(j = 1; j < e; j++) 136 { 137 int l = f[q[j].x1]; 138 int r = f[q[j].x2]-1; 139 // cout<<q[i].f<<" "<<i<<endl; 140 if(l<=r) 141 { 142 update(l,r,q[j].f,1,o-1,1); 143 } 144 LL sum = (LL)(q[j+1].y-q[j].y)*s[1][2]; 145 //cout<<sum<<" ."<<i<<" "<<s[1][2]<<endl; 146 ans+=sum; 147 } 148 } 149 printf("Case %d: %I64d\n",++kk,ans); 150 } 151 return 0; 152 }