刚开始看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 }
hdu3642Get The Treasury,布布扣,bubuko.com
时间: 2024-10-05 20:38:36