题目链接:Overlapping Rectangles 面积并模板题,类似题还有HDU1542
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x7fffffff
typedef long long ll;
using namespace std;
const int maxn = 2010;
struct Seg{
double l;
double r;
double h;
int s;
Seg(){};
Seg(double a,double b,double c,int d) : l(a),r(b),h(c),s(d){};
bool operator < (const Seg &cmp) const{
return h < cmp.h;
}
}ss[maxn<<2];
double X[maxn<<2];
double sum[maxn<<2];
int cnt[maxn<<2];
int bs(double key,int kind,double X[]){
int l = 0, r = kind-1, mid;
while(l <= r){
mid = (l+r)>>1;
if(X[mid] == key) return mid;
else if(X[mid] < key) l = mid+1;
else r = mid-1;
}
return -1;
}
void PushUp(int rt,int L,int R){
if(cnt[rt]) sum[rt] = X[R+1] - X[L];
else if(L == R) sum[rt] = 0;
else sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void update(int l,int r,int c,int L,int R,int rt){
if(l <= L && R <= r){
cnt[rt] += c;
PushUp(rt,L,R);
return;
}
int mid = (L+R)>>1;
if(l <= mid) update(l,r,c,L,mid,rt<<1);
if(mid < r) update(l,r,c,mid+1,R,rt<<1|1);
PushUp(rt,L,R);
}
int main(){
int n,m;
double x1,y1,x2,y2;
while(scanf("%d",&n)){
if(n == 0){
puts("*");
break;
}
m = 0;
for(int i = 0; i < n; i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
X[m] = x1;
ss[m++] = Seg(x1,x2,y1,1);
X[m] = x2;
ss[m++] = Seg(x1,x2,y2,-1);
}
sort(X,X+m);
sort(ss,ss+m);
int kind = 1;
for(int i = 1; i < m; i++){
if(X[i] != X[i-1]) X[kind++] = X[i];
}
memset(cnt,0,sizeof(cnt));
memset(sum,0,sizeof(sum));
double ans = 0;
for(int i = 0; i < m-1; i++){
int l = bs(ss[i].l,kind,X);
int r = bs(ss[i].r,kind,X) - 1;
if(l <= r){
update(l,r,ss[i].s,0,kind-1,1);
}
ans += sum[1]*(ss[i+1].h - ss[i].h);
}
printf("%.0lf\n",ans);
}
return 0;
}