1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
| /*
ID: du331691
PROG: picture
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn=5003;
const int maxx=10003;
int n;
template<typename T>
void read(T& w)
{
char r;bool f=false;
for(r=getchar();(r<48||r>57)&&r!='-';r=getchar());
if(r=='-')r=getchar(),f=true;
for(w=0;r>=48&&r<=57;r=getchar())w=w*10+r-48;
if(f)w=-w;
}
int toxx[maxx*2+1],toyy[maxx*2+1];
int* tox=&toxx[maxx];
int* toy=&toyy[maxx];
struct EDGE
{
int a,b,p;//a<b
bool isl;
void init(int aa,int bb,int pp,bool isll)
{
a=aa,b=bb,p=pp;
isl=isll;
}
}vedge[maxn*2],hedge[maxn*2];
int vk=0,hk=0;
bool operator<(const EDGE& a,const EDGE& b)
{
if(a.p!=b.p)return a.p<b.p;
if(a.isl!=b.isl)return a.isl;
if(a.a!=b.a)return a.a<b.a;
if(a.b!=b.b)return a.b<b.b;
return false;
}
int sx[maxn*2],sy[maxn*2];
int sxk=0,syk=0;
struct RECTANGLE
{
int ax,ay,bx,by;//lower left, upper right
void input()
{
read(ax),read(ay),read(bx),read(by);
sx[++sxk]=ax,sx[++sxk]=bx;
sy[++syk]=ay,sy[++syk]=by;
}
void addEdge()
{
vedge[++vk].init(ay,by,ax,true);
vedge[++vk].init(ay,by,bx,false);
hedge[++hk].init(ax,bx,ay,true);
hedge[++hk].init(ax,bx,by,false);
}
}rect[maxn];
int d[maxn*2];
//d[i]存放第i条边区间的长度
int f[maxn*2],c[maxn*2];
//f[i] 表示在离散化后第i个点以下的一段边的编号
int idx=0,idy=0;
struct SEQ
{
int l,r,num,mid,len,sum,tag;
void build(int numm,int ll,int rr);
void add(int ll,int rr,int k);
}seq[maxx<<4];
#define root seq[1]
#define lc seq[num<<1]
#define rc seq[num<<1|1]
void SEQ::build(int numm,int ll,int rr)
{
num=numm,l=ll,r=rr,mid=(l+r)>>1;
if(l==r)
{
len=d[l];
sum=tag=0;
}
else
{
lc.build(num<<1,ll,mid);
rc.build(num<<1|1,mid+1,rr);
sum=lc.sum+rc.sum;
}
}
void SEQ::add(int ll,int rr,int k)
{
if(l==r)
{
tag+=k;
sum=int(bool(tag))*len;
}
else
{
if(rr<=mid)
lc.add(ll,rr,k);
else if(ll>mid)
rc.add(ll,rr,k);
else lc.add(ll,mid,k),rc.add(mid+1,rr,k);
sum=lc.sum+rc.sum;
}
}
void input()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
rect[i].input();
rect[i].addEdge();
}
}
typedef unsigned int uint;
const uint uinf=4294967295u;
uint ans=0;
void solve()
{
sort(sy+1,sy+syk+1);
for(int i=1,last=0;i<=syk;++i)
{
if(!toy[sy[i]])
{
toy[sy[i]]=++idy;
f[idy]=idy-1;
c[idy]=idy;
d[idy-1]=sy[i]-last;
last=sy[i];
}
}
root.build(1,1,idy);
sort(vedge+1,vedge+vk+1);
for(int i=1,last=0;i<=vk;++i)
{
if(vedge[i].isl)
root.add(c[toy[vedge[i].a]],f[toy[vedge[i].b]],1);
else
root.add(c[toy[vedge[i].a]],f[toy[vedge[i].b]],-1);
int detal=abs(root.sum-last);
ans+=uint(detal);
last=root.sum;
}
memset(f,0,sizeof(f));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
sort(sx+1,sx+sxk+1);
for(int i=1,last=0;i<=sxk;++i)
{
if(!tox[sx[i]])
{
tox[sx[i]]=++idx;
f[idx]=idx-1;
c[idx]=idx;
d[idx-1]=sx[i]-last;
last=sx[i];
}
}
root.build(1,1,idx);
sort(hedge+1,hedge+hk+1);
for(int i=1,last=0;i<=hk;++i)
{
if(hedge[i].isl)
root.add(c[tox[hedge[i].a]],f[tox[hedge[i].b]],1);
else
root.add(c[tox[hedge[i].a]],f[tox[hedge[i].b]],-1);
int detal=abs(root.sum-last);
ans+=uint(detal);
last=root.sum;
}
}
int main()
{
freopen("picture.in","r",stdin);
freopen("picture.out","w",stdout);
input();
solve();
printf("%u\n",ans);
return 0;
}
|