http://acm.pku.edu.cn/JudgeOnline/problem?id=1177

#include<iostream>
#include<algorithm>
#define MAXN 10005
using namespace std;

struct segment
  {
int L,R;
int len,linenum,cover;
// 以当前区间为根的树被覆盖的区间的总长度,
// 以当前区间为根的树被覆盖的区间数目,当前区间被覆盖的次数,
bool lcover,rcover;
};

struct line
  {
//int start,end;//离散化之后竖边的两个Y值
int x;
int flag;//记录左右边
bool operator<( const line &a )
 {
return x<a.x;
}
};

struct point
  {
int y;
int num;
bool operator<( const point & a )
 {
return y<a.y;
}
};

segment tree[MAXN*4];
line yline[MAXN];
point Ypoint[MAXN];
point Xpoint[MAXN];
int Xpost[MAXN][2];
int Ypost[MAXN][2];

void make_tree( int v, int l, int r )
  {
int mid;
tree[v].L=l; tree[v].R=r;
tree[v].linenum=tree[v].len=0;
tree[v].lcover=tree[v].rcover=false;
if( r-l>1 )
 {
mid=(l+r)>>1;
make_tree( v<<1, l, mid );
make_tree( (v<<1)+1, mid, r );
}
}

void getline( int v ) // 获得以当前接点为根的树被覆盖的区间总长度
  {
if( tree[v].cover>0 )tree[v].len=Ypoint[tree[v].R].y-Ypoint[tree[v].L].y;
else if( tree[v].R-tree[v].L==1 )tree[v].len=0;
else tree[v].len=tree[v<<1].len+tree[(v<<1)+1].len;
}

void getlinenum( int v ) //获得以当前节点为树根的子树被覆盖区间的总数
  {
if( tree[v].cover>0 )
tree[v].lcover=tree[v].rcover=true,tree[v].linenum=1;
else if( tree[v].R-tree[v].L==1 )
tree[v].lcover=tree[v].rcover=false,tree[v].linenum=0;
else
 {
tree[v].lcover=tree[v<<1].lcover;
tree[v].rcover=tree[(v<<1)+1].rcover;
tree[v].linenum=tree[v<<1].linenum+tree[(v<<1)+1].linenum-tree[v<<1].rcover*tree[(v<<1)+1].lcover;
}
}

void update( int v, int l, int r, int flag )
  {
int mid;
if( tree[v].L==l && tree[v].R==r )
 {
tree[v].cover+=flag;
getline( v );
getlinenum( v );
return ;
}
mid=(tree[v].L+tree[v].R)>>1;
if( r<=mid )update( v<<1, l, r, flag );
else if( l>=mid )update( (v<<1)+1, l, r, flag );
else
 {
update( v<<1, l, mid, flag );
update( (v<<1)+1, mid, r, flag );
}
getline( v );
getlinenum( v );
}

int main( )
  {
int n,i,t1,t2;
int x1,x2,y1,y2;
while( scanf("%d",&n) != EOF )
 {
for( i=0; i<n; i++ )
 {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
t1=i<<1;t2=(i<<1)+1;
Xpoint[t1].y=x1;Xpoint[t2].y=x2;
Xpoint[t1].num=-(i+1);
Xpoint[t2].num=i+1;
Ypoint[t1].y=y1;Ypoint[t2].y=y2;
Ypoint[t1].num=-(i+1); //竖边下面的点
Ypoint[t2].num=i+1; //竖边上面的点
yline[t1].x=x1;yline[t2].x=x2;
yline[t1].flag=1;//负号矩形左边
yline[t2].flag=-1;//正号矩形右边
}
sort( yline, yline+(n<<1) );
sort( Xpoint, Xpoint+(n<<1) );
sort( Ypoint, Ypoint+(n<<1) );
for( i=0; i<(n<<1); i++ )
 {
if( Xpoint[i].num<0 )Xpost[-Xpoint[i].num-1][0]=i;
else Xpost[Xpoint[i].num-1][1]=i;
}
for( i=0; i<(n<<1); i++ )
 {
if( Ypoint[i].num<0 )
Ypost[Xpost[-Ypoint[i].num-1][0]][0]=Ypost[Xpost[-Ypoint[i].num-1][1]][0]=i;
else Ypost[Xpost[Ypoint[i].num-1][0]][1]=Ypost[Xpost[Ypoint[i].num-1][1]][1]=i;
}
make_tree( 1, 0, (n<<1)-1 );
int ans=0,Len=0;
update( 1, Ypost[0][0], Ypost[0][1], yline[0].flag );
for( i=1; i<2*n; i++ )
 {
ans+=2*tree[1].linenum*(yline[i].x-yline[i-1].x);
ans+=abs(tree[1].len-Len);
Len=tree[1].len;
update( 1, Ypost[i][0], Ypost[i][1], yline[i].flag );
}
ans+=abs(tree[1].len-Len);
printf("%d\n",ans);
}
return 0;
}



|