题目地址:HDU 1255
这题跟面积并的方法很像,只不过需要再加一个变量。
刚开始我以为直接用那个变量就行,只不过判断是否大于0改成判断是否大于1。但是后来发现了个问题,因为这个没有下放,没延迟,比如,在父节点上加了一次1,在该父节点的子节点上又加了一次1,但是这时候所有的结点仍然没有达到2的,但是实际上子节点已经达到2了。这时候可以再加一个变量。那个变量用来保存覆盖数大于等于0的情况,这样的话当计算大于1的覆盖节点的时候,当判断为1的时候就要加上子节点的所有情况,因为字节点是大于0的,加上子节点的说明该父节点也是大于1的。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 int lazy[10000], cnt; double sum[10000], c[10000], once[10000]; struct node { double l, r, h; int f; } edge[100000]; int cmp(node x, node y) { return x.h<y.h; } void add(double l, double r, double h, int f) { edge[cnt].l=l; edge[cnt].r=r; edge[cnt].h=h; edge[cnt++].f=f; } void PushUp(int l, int r, int rt) { if(lazy[rt]>=2) { once[rt]=sum[rt]=c[r+1]-c[l]; } else if(lazy[rt]==1) { once[rt]=c[r+1]-c[l]; if(l==r) { sum[rt]=0; } else sum[rt]=once[rt<<1]+once[rt<<1|1]; } else { if(l==r) once[rt]=sum[rt]=0; else { once[rt]=once[rt<<1]+once[rt<<1|1]; sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } } } void update(int ll, int rr, int x, int l, int r,int rt) { if(ll<=l&&rr>=r) { lazy[rt]+=x; PushUp(l,r,rt); return ; } int mid=l+r>>1; if(ll<=mid) update(ll,rr,x,lson); if(rr>mid) update(ll,rr,x,rson); PushUp(l,r,rt); } int erfen(double x, int high) { int low=0, mid; while(low<=high) { mid=low+high>>1; if(c[mid]==x) return mid; else if(c[mid]>x) high=mid-1; else low=mid+1; } } int main() { int t, n, i, j, k; double x1, x2, y1, y2, ans; scanf("%d",&t); while(t--) { ans=0; memset(sum,0,sizeof(sum)); memset(lazy,0,sizeof(lazy)); memset(once,0,sizeof(once)); scanf("%d",&n); k=0; cnt=0; for(i=0; i<n; i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); c[k++]=x1; c[k++]=x2; add(x1,x2,y1,1); add(x1,x2,y2,-1); } sort(edge,edge+2*n,cmp); sort(c,c+k); for(i=0; i<2*n-1; i++) { int l=erfen(edge[i].l,2*n-1); int r=erfen(edge[i].r,2*n-1); //printf("%d %d\n",l,r); update(l,r-1,edge[i].f,0,2*n-1,1); ans+=sum[1]*(edge[i+1].h-edge[i].h); //printf("%.2lf %.2lf\n",sum[1],edge[i+1].h-edge[i].h); } printf("%.2lf\n",ans); } return 0; }
HDU 1255 覆盖的面积(线段树+扫描线),布布扣,bubuko.com
原文:http://blog.csdn.net/scf0920/article/details/38509975