贴几个大佬的博客帮助理解
https://blog.csdn.net/xingyeyongheng/article/details/8927732
http://www.aizhuanji.com/a/AWbkpGxj.html
https://www.cnblogs.com/liwenchi/p/7259171.html
https://blog.csdn.net/qq_18661257/article/details/47658191
http://www.cnblogs.com/fenshen371/p/3214092.html
因为线段树节点存的是区间的长度,那么就导致叶子节点单独的一个数就没有意义了,所以这里采用了[)左闭右开的这种写法,这样就有意义了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MOD 1e9+7
#define PI acos(-1)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 222;
int n;
struct node {
double l, r, h; //标记线段位置及高度
int flag;//标记上下边
node() {} //不懂为什么这么写,但是没有这一句就不能像下面一样使用初始化列表
node(double a, double b, double c, int d): l(a), r(b), h(c), flag(d) {}
bool operator <(const node &a)const {//重载< 用于下面的排序
return h < a.h;
}
} ss[maxn << 2];
double sum[maxn << 2]; //记录面积
int cover[maxn << 2]; //记录是否被覆盖
double Hash[maxn];//离散化数组,一开始开成了int却是MLE,好奇怪
int my_search(double key, int k) {//因为不能使用lower_bound(),所以只好自己手写二分查找
int l = 0;
int r = k - 1;//因为Hash是从0开始存的,所以范围是[0,k-1]
while(l <= r) {
int mid = (l + r) >> 1;
if(Hash[mid] == key) return mid;
else if(Hash[mid] > key) r = mid - 1;
else l = mid + 1;
}
return -1;
}
void push_up(int rt, int l, int r) {
if(cover[rt]) sum[rt] = Hash[r + 1] - Hash[l];
/*如果这个节点已经被完全覆盖,那么长度就是右边减左边z
注意这里要+1
*/
else if(l == r) sum[rt] = 0;//当前是一个点,不是很懂
else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];//如果当前这个区间没有被完全覆盖,区间长度就是他的子区间的和
}
void updata(int L, int R, int flag, int l, int r, int rt) {
if(L <= l && r <= R) {
cover[rt] += flag;//更新cover
push_up(rt, l, r);
return;
}
int m = (l + r) >> 1;
if(L <= m) updata(L, R, flag, lson);
if(R > m) updata(L, R, flag, rson);
push_up(rt, l, r);
return ;
}
int main() {
int cas = 0;
while(~scanf("%d", &n), n) {
memset(sum, 0, sizeof(sum));
memset(cover, 0, sizeof(cover));
cas++;
int cnt = 0;
for(int i = 1; i <= n; i++) {
double x1, x2, y1, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
ss[cnt] = {x1, x2, y1, 1};
Hash[cnt++] = x1;
ss[cnt] = {x1, x2, y2, -1};
Hash[cnt++] = x2;
}
sort(ss, ss + cnt);
sort(Hash, Hash + cnt);
int k = unique(Hash, Hash + cnt) - Hash;//去重
double ans = 0;
for(int i = 0; i < cnt - 1; i++) {
int l = my_search(ss[i].l, k);
int r = my_search(ss[i].r, k) - 1;
updata(l, r, ss[i].flag, 0, k - 1, 1);
ans += sum[1] * (ss[i + 1].h - ss[i].h);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", cas, ans);
}
return 0;
}