题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255
题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和。
因为n只有1000,所以我离散化一下,数据大小就缩小了,那么之后只需要线段树单点更新就好了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int MAXN = 4e3 + ;
struct data {
int x1 , x2 , flag;
double y , xx1 , xx2;
bool operator <(const data& cmp) const {
return y < cmp.y;
}
}a[MAXN];
struct segtree {
int l , r , add;
double val;
}T[MAXN << ];
double x[MAXN];
map <double , int> mp; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].val = T[p].add = , T[p].l = l , T[p].r = r;
if(r - l == ) {
return ;
}
build(p << , l , mid);
build((p << )| , mid , r);
} void updata(int p , int l , int r , int val) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].r - T[p].l == ) {
T[p].add += val;
if(T[p].add > )
T[p].val = x[T[p].r] - x[T[p].l];
else
T[p].val = ;
return ;
}
if(r <= mid) {
updata(p << , l , r , val);
}
else if(l >= mid) {
updata((p << )| , l , r , val);
}
else {
updata(p << , l , mid , val);
updata((p << )| , mid , r , val);
}
T[p].val = T[p << ].val + T[(p << )|].val;
} int main()
{
int t = , n;
double x1 , x2 , y1 , y2;
scanf("%d" , &t);
while(t--) {
mp.clear();
scanf("%d" , &n);
int cnt = ;
for(int i = ; i < n ; i++) {
scanf("%lf %lf %lf %lf" , &x1 , &y1 , &x2 , &y2);
if(x1 > x2)
swap(x1 , x2);
if(y1 > y2)
swap(y1 , y2);
int ls = i * , rs = i * + ;
a[ls].xx1 = x1 , a[ls].xx2 = x2 , a[ls].y = y1 , a[ls].flag = ;
a[rs].xx1 = x1 , a[rs].xx2 = x2 , a[rs].y = y2 , a[rs].flag = -;
if(!mp[x1]) {
mp[x1] = ;
x[++cnt] = x1;
}
if(!mp[x2]) {
mp[x2] = ;
x[++cnt] = x2;
}
}
sort(a , a + n * );
sort(x + , x + cnt + );
for(int i = ; i < n * ; i++) {
a[i].x1 = lower_bound(x + , x + cnt + , a[i].xx1) - x;
a[i].x2 = lower_bound(x + , x + cnt + , a[i].xx2) - x;
}
double res = ;
build( , , cnt);
updata( , a[].x1 , a[].x2 , a[].flag);
for(int i = ; i < * n ; i++) {
res += (a[i].y - a[i - ].y) * T[].val;
updata( , a[i].x1 , a[i].x2 , a[i].flag);
}
printf("%.2f\n" , res);
}
}