第四次写线段树,把之前那道覆盖一次以上面积的题改了改拿过来。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
struct Node
{
int l,r;
int c;
int lf,rf;
int one;
}tree[6010];
struct Line
{
int x,u,d;
int flag;
}line[2010];
int y[2010];
int n;
bool cmp(Line a,Line b)
{
return a.x<b.x;
}
struct segment_tree{
void build(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].one=0;
tree[rt].lf=y[l];
tree[rt].rf=y[r];
if (l+1==r)
{
return;
}
int mid=l+r>>1;
build(l,mid,rt*2);
build(mid,r,rt*2+1);
}
void update(int rt,Line e)
{
//cout<<"treelf="<<tree[rt].lf<<" ed="<<e.d<<" rteerf="<<tree[rt].rf<<" eu="<<e.u<<endl;
if (tree[rt].lf==e.d && tree[rt].rf==e.u)
{
tree[rt].c+=e.flag;
query(rt);
return;
}
if (e.u<=tree[rt*2].rf) update(rt*2,e);
else if (e.d>=tree[rt*2+1].lf) update(rt*2+1,e);
else
{
Line tmp=e;
tmp.u=tree[rt*2].rf;
update(rt*2,tmp);
tmp=e;
tmp.d=tree[rt*2+1].lf;
update(rt*2+1,tmp);
}
query(rt);
}
void query(int rt)
{
if (tree[rt].c>=2)
{
tree[rt].one=tree[rt].rf-tree[rt].lf;
return;
}
else if (tree[rt].c==1)
{
tree[rt].one=tree[rt].rf-tree[rt].lf;
}else
{
if (tree[rt].l+1==tree[rt].r)
{
tree[rt].one=0;
}else
{
tree[rt].one=tree[rt*2].one+tree[rt*2+1].one;
}
}
}
};
int main()
{
int x1,x2,y1,y2,cnt;
while (~scanf("%d%d%d%d",&x1,&y1,&x2,&y2))
{
cnt=1;
y[cnt]=y1; line[cnt].x=min(x1,x2); line[cnt].d=min(y1,y2); line[cnt].u=max(y1,y2); line[cnt].flag=1; cnt++;
y[cnt]=y2; line[cnt].x=max(x1,x2); line[cnt].d=min(y1,y2); line[cnt].u=max(y1,y2); line[cnt].flag=-1; cnt++;
while (~scanf("%d%d%d%d",&x1,&y1,&x2,&y2) && x1!=-1 && x1!=-2)
{
y[cnt]=y1; line[cnt].x=min(x1,x2); line[cnt].d=min(y1,y2); line[cnt].u=max(y1,y2); line[cnt].flag=1; cnt++;
y[cnt]=y2; line[cnt].x=max(x1,x2); line[cnt].d=min(y1,y2); line[cnt].u=max(y1,y2); line[cnt].flag=-1; cnt++;
}
sort(y+1,y+cnt);
sort(line,line+cnt,cmp);
segment_tree tmp;
tmp.build(1,cnt-1,1);
tmp.update(1,line[1]);
int ans=0;
for (int i=2; i<cnt; i++)
{
ans+=tree[1].one*(line[i].x-line[i-1].x);
//cout<<"i="<<i<<endl;
tmp.update(1,line[i]);
}
printf("%d\n",ans);
if (x1==-2) break;
}
return 0;
}