Description
Input
Output
Sample Input
2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
Sample Output
7.63 0.00AC代码:/* 这题一开始是想找题解的,所以当我找了题解后,发现 有人一样是不会做这个的,只做了面积并,而且他YY过了 所以我也决定要YY过它,所以就没有看题解了。没想到 过了一晚时间就让我YY过了,哈哈!! */ #include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> using namespace std; #define T 10005 #define lson (rt<<1) #define rson (rt<<1|1) typedef long long ll; int n; //离散化数组 double pos[T]; //保存y在x区间的边 struct line { double y,x_up,x_down; int flag; bool operator<(const line& a)const{ return y<a.y; } line(double _1,double _2,double _3,int _4): y(_1),x_up(_2),x_down(_3),flag(_4){} line(){} }p[T]; //线段树数组 struct node { int L,R; double len; int mid; int flag; }tree[T]; //向上更新 void pushup(int rt) { if(tree[rt].flag>=2){//完全覆盖区间 tree[rt].len = pos[tree[rt].R-1]-pos[tree[rt].L-1]; } else if(tree[rt].L+1==tree[rt].R){//叶子节点 tree[rt].len = 0; } else//跨越几个区间合并值 { tree[rt].len = tree[lson].len+tree[rson].len; /*tree[lson].len = 0,tree[rson].len=0;*/ } } /* 这题与面积并相像,只是多了一个向下更新,之所以要向下 更新是因为,我要的是单个区间都要有值 */ void pushdown(int rt) { if(tree[rt].flag){ tree[lson].flag += tree[rt].flag; tree[rson].flag += tree[rt].flag; tree[rt].flag = 0; } } //建树 void build(int rt,int L,int R) { tree[rt].L = L; tree[rt].R = R; tree[rt].flag = 0; tree[rt].len = 0; tree[rt].mid = (L+R)>>1; if(L+1!=R){ build(lson,L,tree[rt].mid); build(rson,tree[rt].mid,R); } } //更新 void update(int rt,int L,int R,int w) { /* 一开始答案存在偏差,弄了好久发现只要符合范围就返回 所以有些区间是将值传递下去了,结果却因为没下去所以 漏掉了一些面积,之后一直在调整pushdown函数,结果一直 没结果,换成只在区间才返回后就不存在这种情况了。应该 可以用懒惰性标记吧 */ if(L<=tree[rt].L&&tree[rt].R<=R&&tree[rt].L+1==tree[rt].R){ tree[rt].flag+=w; pushup(rt); return; } pushdown(rt); if(R<=tree[rt].mid) update(lson,L,R,w); else if(L>=tree[rt].mid) update(rson,L,R,w); else{ update(lson,L,tree[rt].mid,w); update(rson,tree[rt].mid,R,w); } pushup(rt); } int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int i,c,N; double x1,x2,y1,y2; scanf("%d",&N); while(N--) { scanf("%d",&n); c = 0; for(i=0;i<n;++i){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); pos[c] = x1; p[c++] = line(y1,x1,x2,1); pos[c] = x2; p[c++] = line(y2,x1,x2,-1); } sort(pos,pos+c); int d = unique(pos,pos+c)-pos; build(1,1,d); sort(p,p+c); double ans=0; for(i=0;i<c-1;++i){ //因为离散化了,所以要找x的下标 int a = lower_bound(pos,pos+d,p[i].x_up)-pos+1; int b = lower_bound(pos,pos+d,p[i].x_down)-pos+1; //更新x区间(a,b)的值 update(1,a,b,p[i].flag); ans+=tree[1].len*(p[i+1].y-p[i].y); } printf("%.2lf\n",ans); } return 0; }