hdu - 1255
世事总是如此地无常,很多事情总在意料之外。
比如,这题。
不知道是如何错的,是因为二分写得不好?
做完矩形周长并之后,就把这个代码加了两个0,就过了。
又是maxn开小了。
下面是正确代码。
建议: 学矩形周长并、面积交,先学矩形面积并。
Pro: 0
Sol:
date:
*/
#include<iostream>
#include <cstdio>
#include<algorithm>
#include <cstring>
#define eps 1e-10
#define maxn 101000
#define lson l,m, rt << 1
#define rson m + 1,r, rt << 1 | 1
using namespace std;
struct Seg{
double l,r,y;
int sign;
Seg(){}
Seg(double ll, double rr, double yy, int ss):l(ll),r(rr),y(yy),sign(ss){}
bool operator < (const Seg &cmp) const{
if(y == cmp.y) return sign > cmp.sign;
return y < cmp.y;
}
}seg[maxn << 1];
//sum存的是全部被覆盖的长度,rep存的是被重复覆盖的长度
double sum[maxn << 2],rep[maxn];
//c存的是该区间被覆盖几次
int c[maxn << 2];
//存的是原值,用于离散化
double X[maxn << 1];
void push_up(int rt,int l, int r){
if(c[rt]) sum[rt] = X[r + 1] - X[l];
else if(l == r) sum[rt] = 0.0;
else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
if(c[rt] >= 2) rep[rt] = X[r + 1] - X[l];
else if(l == r) rep[rt] = 0.0;
//这里需要讨论一下
else if(c[rt] == 1) rep[rt] = sum[rt << 1] + sum[rt << 1 | 1];
else rep[rt] = rep[rt << 1] + rep[rt << 1 | 1];
}
void update(int L, int R, int ss, int l , int r, int rt){
if(L <= l && r <= R){
c[rt] += ss;
push_up(rt,l,r); return;
}
int m = (l + r) >> 1;
if(L <= m) update(L,R,ss,lson);
if(R > m) update(L,R,ss,rson);
push_up(rt,l,r);
}
//二分的时候对double注意
//int bin(int low, int high, double key){
// int mid;
// while(low < high){
// mid = (low + high) >> 1;
// if(X[mid] - key + eps < 0) low = mid + 1;
// else high = mid;
// }
// return low;
//}
int bin(int low, int high, double key){
int mid;
while(low <= high){
mid = (low + high) >> 1;
if(X[mid] == key) return mid;
if (X[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
int n,xx,t,s,p;
double x1,x2,y1,y2,ret;
void init(){
memset(sum,0,sizeof(sum));
memset(rep,0,sizeof(rep));
memset(c,0,sizeof(c));
s=0; xx= 0; p = 1; ret = 0.0;
return;
}
int main(){
scanf("%d",&t);
while(t --){
scanf("%d",&n) ;
init();
for(int i = 0; i < n; i ++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
seg[s ++] = Seg(x1,x2,y1,1);
seg[s ++] = Seg(x1,x2,y2,-1);
X[xx ++] = x1;
X[xx ++] = x2;
}
sort(X,X+xx);
for(int i = 1; i < xx; i ++){
if(X[i - 1] != X[i]) X[p ++] = X[i];
}
sort(seg,seg+s); p --;
for(int i = 0; i < s - 1; i ++){
int l = bin(0,p,seg[i].l);
int r = bin(0,p,seg[i].r) - 1;
// cout << l << " " << r << endl;
if(l <= r) update(l,r,seg[i].sign,0,p - 1,1);
// cout << rep[1] << "###" << endl;
// cout << sum[1] << "&&&" << endl;
ret += rep[1] * (seg[i + 1].y - seg[i].y);
}
printf("%.2lf\n",ret);
}
return 0;
}