传送门:http://lightoj.com/volume_showproblem.php?problem=1120
Time Limit:2 second(s) | Memory Limit:64 MB |
Given some axis parallel rectangles, you have to find the union of their area. For example, see the shaded regions in the picture. Each rectangle will be denoted by four integers. They arex1, y1, x2, y2where(x1, y1)denotes the lower left corner and(x2, y2)denotes the upper right corner.
For the picture above, there are three rectangles. For the yellow rectangle the co-ordinates are (0, 2) and (3, 6). For the blue rectangle the co-ordinates are (1, 3) and (6, 7). For the green rectangle the co-ordinates are (2, 1) and (5, 4). So, the union area is (the shaded region) 31 square units.
Input
Input starts with an integerT (≤ 13), denoting the number of test cases.
Each case starts with a line containing an integern (1 ≤ n ≤ 30000). Each of the nextnlines will contain four integersx1, y1, x2, y2(0 ≤ x1, y1, x2, y2≤ 109, x1< x2, y1< y2)denoting a rectangle.
Output
For each case, print the case number and the union area.
Sample Input | Output for Sample Input |
2 3 0 2 3 6 1 3 6 7 2 1 5 4 2 0 0 4 4 1 1 2 5 | Case 1: 31 Case 2: 17 |
Notes
Dataset is huge, use faster I/O methods.
题意:很裸就矩形面积并,直接扫描线.
注意点:由于面积最大可以达到10^18次方,所以结果需要用long long,而且在中间计算时需要强制转换,否则会溢出.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 33333;
int x[MAXN<<1],t,n,sum[MAXN<<3],cnt[MAXN<<3],x_num,line_num;
unsigned __int64 ans;
struct Line{
int l,r,h,s;
Line(){}
Line(int ll,int rr,int hh,int ss):l(ll),r(rr),h(hh),s(ss){}
bool operator < (const Line &l) const{
return h<l.h;
}
}L[MAXN<<1];
#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
void build(){
memset(sum,0,sizeof(sum));
memset(cnt,0,sizeof(cnt));
x_num = line_num = 0;
ans = 0;
}
void pushUP(int rt,int l,int r){
if(cnt[rt]){
sum[rt] = x[r]-x[l];
}else{
sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
}
void update(int L,int R,int s,int l,int r,int rt){
if(L<=l&&R>=r){
cnt[rt]+=s;
pushUP(rt,l,r);
return;
}
if(l==r-1)return;
int m = (l+r)>>1;
if(m>L)update(L,R,s,lson);
if(m<R)update(L,R,s,rson);
pushUP(rt,l,r);
}
int search(int k){
int l=0,r=x_num-1,m;
while(l<=r){
m = (l+r)>>1;
if(x[m]==k)return m;
else if(k<x[m])r = m-1;
else l = m+1;
}
return -1;
}
int main(){
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
scanf("%d",&n);
build();
for(int i=0;i<n;i++){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
x[x_num++] = a;
x[x_num++] = c;
L[line_num++] = Line(a,c,b,1);
L[line_num++] = Line(a,c,d,-1);
}
sort(x,x+x_num);sort(L,L+line_num);
int temp = 1;
for(int i=1;i<x_num;i++)if(x[i]!=x[i-1])x[temp++]=x[i];
x_num = temp;
for(int i=0;i<line_num;i++){
int l = search(L[i].l);
int r = search(L[i].r);
if(!i){
update(l,r,L[i].s,0,x_num-1,1);
}else{
ans += (__int64)sum[1]*(L[i].h-L[i-1].h);
update(l,r,L[i].s,0,x_num-1,1);
}
}
printf("Case %d: %llu\n",cas,ans);
}
return 0;
}