题目大意:一个二维平面内有一些矩形,坐标范围0-100;求覆盖的1*1单位面积的个数,重复覆盖的算1次。
题目分析:可以用经典的一维线段树+扫描线求面积并,但此题数据量太小,0-100,而且都是整点,所以二维线段树直接水过。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105;
struct node
{
int num;
int area;
int tree[N<<2];
void build(int num,int s,int e)
{
tree[num] = 0;
if(s == e)
return;
int mid = (s + e)>>1;
build(num<<1,s,mid);
build(num<<1|1,mid + 1,e);
}
void insert(int num,int s,int e,int l,int r)
{
if(tree[num] == e - s + 1)
return;
if(s == l && e == r)
{
tree[num] = e - s + 1;
return;
}
int mid = (s + e)>>1;
if(r <= mid)
insert(num<<1,s,mid,l,r);
else
{
if(l > mid)
insert(num<<1|1,mid + 1,e,l,r);
else
{
insert(num<<1,s,mid,l,mid);
insert(num<<1|1,mid + 1,e,mid + 1,r);
}
}
tree[num] = tree[num<<1] + tree[num<<1|1];
}
}seg[N<<2];
void build(int num,int s,int e)
{
seg[num].num = seg[num].area = 0;
seg[num].build(1,1,101);
if(s == e)
return;
int mid = (s + e)>>1;
build(num<<1,s,mid);
build(num<<1|1,mid + 1,e);
}
void insert(int num,int s,int e,int x1,int x2,int y1,int y2)
{
if(s == e)
{
seg[num].insert(1,1,101,y1,y2);
seg[num].num = seg[num].tree[1];
return;
}
int mid = (s + e)>>1;
if(x2 <= mid)
insert(num<<1,s,mid,x1,x2,y1,y2);
else
{
if(x1 > mid)
insert(num<<1|1,mid + 1,e,x1,x2,y1,y2);
else
{
insert(num<<1,s,mid,x1,mid,y1,y2);
insert(num<<1|1,mid + 1,e,mid + 1,x2,y1,y2);
}
}
seg[num].num = seg[num<<1].num + seg[num<<1|1].num;
}
int main()
{
int x1,x2,y1,y2,i;
build(1,1,101);
while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2))
{
if(x1 == -2 && y1 == -2 && x2 == -2 && y2 == -2)
{
printf("%d\n",seg[1].num);
break;
}
if(x1 == -1 && x2 == -1 && y1 == -1 && y2 == -1)
{
printf("%d\n",seg[1].num);
build(1,1,101);
}
else
{
if(x1 > x2)
{
x1 ^= x2;
x2 ^= x1;
x1 ^= x2;
}
if(y1 > y2)
{
y1 ^= y2;
y2 ^= y1;
y1 ^= y2;
}
x1 ++;x2 ++;y1 ++;y2 ++;
insert(1,1,101,x1,x2 - 1,y1,y2 - 1);
}
}
return 0;
}
//31MS 712K