http://acm.hdu.edu.cn/showproblem.php?pid=1542
单纯的线段树+扫描线求面积并,需要离散化。
code:
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <list>
#include <ctime>
using namespace std ;
#define SET(arr, what) memset(arr, what, sizeof(arr))
#define FF(i, a) for(i=0; i<a; i++)
#define SD(a) scanf("%d", &a)
#define SSD(a, b) scanf("%d%d", &a, &b)
#define SSF(a, b) scanf("%lf%lf", &a, &b)
#define SS(a) scanf("%s", a)
#define SLD(a) scanf("%lld", &a)
#define PF(a) printf("%d\n", a)
#define PPF(a, b) printf("%d %d\n", a, b)
#define PLF(a) printf("%lf\n", a)
#define SZ(arr) (int)a.size()
#define SWAP(a,b) a=a xor b;b= a xor b;a=a xor b;
#define read freopen("in.txt", "r", stdin)
#define write freopen("out.txt", "w", stdout)
#define MAX 1<<30
#define ESP 1e-5
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline void AMin(T &a,T b){if(a==-1||a>b)a=b;}
template<class T> inline void AMax(T &a,T b){if(a<b)a=b;}
template<class T> inline T Min(T a,T b){return a>b?b:a;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
const int maxn = 2222 ;
int cover[maxn<<2] ;
double sum[maxn<<2], s[maxn] ;
struct Seg{
double l, r, h ;
int d ;
}seg[maxn] ;
int cmp1(const void *a, const void *b){
return (*(Seg *)a).h < (*(Seg *)b).h ? -1 : 1 ;
}
int cmp2(const void *a, const void *b){
return *(double *)a < *(double *)b ? -1 : 1 ;
}
void setSeg(double l, double r, int d, double h, int cnt){
seg[cnt].l = l ;
seg[cnt].r = r ;
seg[cnt].d = d ;
seg[cnt].h = h ;
}
void pushup(int rt, int l, int r){
if(cover[rt]) sum[rt] = s[r+1] - s[l] ;
else if(l==r) sum[rt] = 0 ;
else sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
}
int find(double val, int r){
int l = 0 ;
while(l<=r){
int m = (l + r) >> 1 ;
if(val==s[m]) return m ;
if(val>s[m]) l = m + 1 ;
else r = m - 1 ;
}
return -1 ;
}
void update(int L, int R, int d, int l, int r, int rt){
if(L<=l&&r<=R){
cover[rt] += d ;
pushup(rt, l, r) ;
return ;
}
int m = (l + r) >> 1 ;
if(L<=m) update(L, R, d, lson) ;
if(R>m) update(L, R, d, rson) ;
pushup(rt, l, r) ;
}
int main(){
int n, t=1, i, x, y, j, m ;
double a, b, c, d, ans ;
while(~SD(n)&&n){
x = y = 0 ;
FF(i, n){
SSF(a, b) ;SSF(c, d) ;
s[y++] = a ;
s[y++] = c ;
setSeg(a, c, 1, b, x++) ;
setSeg(a, c, -1, d, x++) ;
}
qsort(seg, x, sizeof(Seg), cmp1) ;
qsort(s, x, sizeof(double), cmp2) ;
m = 1 ;
for(i=1; i<y; i++) if(s[i]!=s[i-1]) s[m++] = s[i] ;
SET(sum, 0) ;
SET(cover, 0) ;
ans = 0 ;
FF(i, x-1){
int l = find(seg[i].l, m-1) ;
int r = find(seg[i].r, m-1) - 1 ;
if(l<=r) update(l, r, seg[i].d, 0, m-1, 1) ;
ans += sum[1] * (seg[i+1].h - seg[i].h) ;
}
printf("Test case #%d\n", t++) ;
printf("Total explored area: %.2lf\n\n", ans) ;
}
return 0 ;
}
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <list>
#include <ctime>
using namespace std ;
#define SET(arr, what) memset(arr, what, sizeof(arr))
#define FF(i, a) for(i=0; i<a; i++)
#define SD(a) scanf("%d", &a)
#define SSD(a, b) scanf("%d%d", &a, &b)
#define SSF(a, b) scanf("%lf%lf", &a, &b)
#define SS(a) scanf("%s", a)
#define SLD(a) scanf("%lld", &a)
#define PF(a) printf("%d\n", a)
#define PPF(a, b) printf("%d %d\n", a, b)
#define PLF(a) printf("%lf\n", a)
#define SZ(arr) (int)a.size()
#define SWAP(a,b) a=a xor b;b= a xor b;a=a xor b;
#define read freopen("in.txt", "r", stdin)
#define write freopen("out.txt", "w", stdout)
#define MAX 1<<30
#define ESP 1e-5
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline void AMin(T &a,T b){if(a==-1||a>b)a=b;}
template<class T> inline void AMax(T &a,T b){if(a<b)a=b;}
template<class T> inline T Min(T a,T b){return a>b?b:a;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
const int maxn = 2222 ;
int cover[maxn<<2] ;
double sum[maxn<<2], s[maxn] ;
struct Seg{
double l, r, h ;
int d ;
}seg[maxn] ;
int cmp1(const void *a, const void *b){
return (*(Seg *)a).h < (*(Seg *)b).h ? -1 : 1 ;
}
int cmp2(const void *a, const void *b){
return *(double *)a < *(double *)b ? -1 : 1 ;
}
void setSeg(double l, double r, int d, double h, int cnt){
seg[cnt].l = l ;
seg[cnt].r = r ;
seg[cnt].d = d ;
seg[cnt].h = h ;
}
void pushup(int rt, int l, int r){
if(cover[rt]) sum[rt] = s[r+1] - s[l] ;
else if(l==r) sum[rt] = 0 ;
else sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
}
int find(double val, int r){
int l = 0 ;
while(l<=r){
int m = (l + r) >> 1 ;
if(val==s[m]) return m ;
if(val>s[m]) l = m + 1 ;
else r = m - 1 ;
}
return -1 ;
}
void update(int L, int R, int d, int l, int r, int rt){
if(L<=l&&r<=R){
cover[rt] += d ;
pushup(rt, l, r) ;
return ;
}
int m = (l + r) >> 1 ;
if(L<=m) update(L, R, d, lson) ;
if(R>m) update(L, R, d, rson) ;
pushup(rt, l, r) ;
}
int main(){
int n, t=1, i, x, y, j, m ;
double a, b, c, d, ans ;
while(~SD(n)&&n){
x = y = 0 ;
FF(i, n){
SSF(a, b) ;SSF(c, d) ;
s[y++] = a ;
s[y++] = c ;
setSeg(a, c, 1, b, x++) ;
setSeg(a, c, -1, d, x++) ;
}
qsort(seg, x, sizeof(Seg), cmp1) ;
qsort(s, x, sizeof(double), cmp2) ;
m = 1 ;
for(i=1; i<y; i++) if(s[i]!=s[i-1]) s[m++] = s[i] ;
SET(sum, 0) ;
SET(cover, 0) ;
ans = 0 ;
FF(i, x-1){
int l = find(seg[i].l, m-1) ;
int r = find(seg[i].r, m-1) - 1 ;
if(l<=r) update(l, r, seg[i].d, 0, m-1, 1) ;
ans += sum[1] * (seg[i+1].h - seg[i].h) ;
}
printf("Test case #%d\n", t++) ;
printf("Total explored area: %.2lf\n\n", ans) ;
}
return 0 ;
}