求最终的覆盖图形周长,写这种代码应该短而精确,差的比较远
/*
Problem: 1177 User: 96655
Memory: 348K Time: 32MS
Language: C++ Result: Accepted
*/
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <algorithm>
using namespace std;
const int maxn=;
struct Node
{
int s,t,num,len,cover;
bool lb,rb;
void change(int o)
{
cover+=o;
if(cover==)len=lb=rb=num=;
else len=t-s,lb=,rb=,num=;
}
} node[maxn<<];
struct Line
{
int x,y1,y2,flag;
void fun(int a,int b,int c,int d)
{
x=a,y1=b,y2=c,flag=d;
}
bool operator<(const Line &e)const
{
if(x==e.x)
return flag>e.flag;
return x<e.x;
}
} line[maxn];
int y[maxn];
void build(int rt,int l,int r)
{
node[rt].s=y[l];
node[rt].t=y[r];
node[rt].num=node[rt].len=node[rt].cover=; if(l+==r)return;
int m=(l+r)>>;
build(rt*,l,m);
build(rt*+,m,r);
}
void update_line(int rt)
{
node[rt].lb=node[rt*].lb;
node[rt].rb=node[rt*+].rb;
node[rt].num=node[rt*].num+node[rt*+].num-node[rt*].rb*node[rt*+].lb;
}
void update_len(int rt)
{
node[rt].len=node[rt*].len+node[rt*+].len;
}
void update(int rt,int l,int r,Line e)
{
if(l+==r)
{
node[rt].change(e.flag);
return;
}
int m=(l+r)>>;
if(e.y1<node[rt*].t)update(rt*,l,m,e);
if(e.y2>node[rt*+].s)update(rt*+,m,r,e);
update_len(rt);
update_line(rt);
}
int main()
{
int n,x1,x2,y1,y2,cnt=,d=;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[++cnt].fun(x1,y1,y2,);
y[cnt]=y1;
line[++cnt].fun(x2,y1,y2,-);
y[cnt]=y2;
}
sort(y+,y++cnt);
sort(line+,line++cnt);
for(int i=; i<=cnt; ++i)
if(y[i]!=y[i-])y[++d]=y[i];
build(,,d);
int perimeter=;
int now_len=;
int now_num=;
for(int i=; i<=cnt; ++i)
{
update(,,d,line[i]);
if(i>)perimeter+=*now_num*(line[i].x-line[i-].x);
perimeter+=abs(node[].len-now_len);
now_num=node[].num;
now_len=node[].len;
}
printf("%d\n",perimeter);
return ;
}