HDU 125 4000 5 覆盖的面积(线段树+面积交)
2017-09-29 20:58
405 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1255
分析:
和求面积并类似 面积并的时候我们只要求出覆盖一次的长度就行 而这里要求出覆盖两次及其以上的长度 分以下情况讨论
1、标记s>=2 覆盖大于等于两次 len1、len2直接求就是了
2、标记s==0 len1、len2都要从左右子区间求解(若为叶子节点 len2为0 覆盖两次是不可能的)
3、标记s==1 len1直接求就是了 若为叶子节点 len2同样为0 如果不是叶子节点 看左右子区间如果有被覆盖过一次的加上这次覆盖 就是两次了
AC代码:
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include <vector> #include <stack> #include <queue> #include <map> #include <set> #include<list> #include <bitset> #include <climits> #include <algorithm> #define gcd(a,b) __gcd(a,b) #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w",stdout) typedef long long LL; const LL mod=1e9+7; const int INF=0x3f3f3f3f; const int MAX=1e3+5; const double PI=acos(-1.0); using namespace std; struct node{// 存储矩形边的信息 double x1,x2,h; int flag;// 出边还是入边 }a[MAX]; struct Tree{ int l,r; double len,len2; int s; }T[MAX]; double ls[MAX];// 离散化 bool cmp(node x,node y){ return x.h<y.h; } void pushUP(int rt){// 标记上推 if (T[rt].s>=2){// 覆盖大于等于两次 T[rt].len=T[rt].len2=ls[T[rt].r+1]-ls[T[rt].l]; } else if (T[rt].s==1){ T[rt].len=ls[T[rt].r+1]-ls[T[rt].l]; if (T[rt].l==T[rt].r) T[rt].len2=0; else T[rt].len2=T[rt*2].len+T[rt*2+1].len; } else { if (T[rt].l==T[rt].r) T[rt].len2=T[rt].len=0; else{ T[rt].len=T[rt*2].len+T[rt*2+1].len; T[rt].len2=T[rt*2].len2+T[rt*2+1].len2; } } } void build(int rt,int l,int r){// 建树 T[rt].s=0;T[rt].len2=0;T[rt].len=0; T[rt].l=l;T[rt].r=r; if (l==r) return ; int mid=(l+r)/2; build(rt*2,l,mid); build(rt*2+1,mid+1,r); } void update(int rt,int l,int r,int e){// 修改区间 if (T[rt].l>=l&&T[rt].r<=r){ T[rt].s+=e; pushUP(rt); return ; } int mid=(T[rt].l+T[rt].r)/2; if (r<=mid) update(rt*2,l,r,e);// 如果在左侧左侧更新 else if (l>mid) update(rt*2+1,l,r,e);// 如果在右侧右侧更新 else{// 两侧都更新 update(rt*2,l,mid,e); update(rt*2+1,mid+1,r,e); } pushUP(rt); } int main (){ int t; //FIN; scanf ("%d",&t); while (t--){ int len=0,n; scanf ("%d",&n); for (int i=0;i<n;i++){ double x1,y1,x2,y2; scanf ("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); a[len].x1=x1;a[len].x2=x2;a[len].h=y1; a[len].flag=1;ls[len]=x1;len++; a[len].x1=x1;a[len].x2=x2;a[len].h=y2; a[len].flag=-1;ls[len]=x2;len++; } sort(ls,ls+len); sort(a,a+len,cmp); len=unique(ls,ls+len)-ls;// 去重 build(1,0,len-1); double ans=0; for (int i=0;i<2*n;i++){ int l=lower_bound(ls,ls+len,a[i].x1)-ls; int r=lower_bound(ls,ls+len,a[i].x2)-ls-1; update(1,l,r,a[i].flag); ans+=T[1].len2*(a[i+1].h-a[i].h); } printf("%.2f\n",ans); } }
相关文章推荐
- HDU - 1255 覆盖的面积(线段树 + 扫描线)
- HDU 1255 覆盖的面积(线段树扫描线)
- HDU-1255 覆盖的面积 (线段树 求矩形覆盖面积)
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- hdu 1255 覆盖的面积(线段树 面积交+离散化)
- hdu 1255 覆盖的面积 (线段树处理面积覆盖问题(模板))
- HDU 1255 覆盖的面积 线段树 扫描线
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
- hdu 1255 覆盖的面积 线段树扫描线求重叠面积
- Hdu 1255 覆盖的面积 线段树+矩形面积并
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- HDU - 1255 覆盖的面积(线段树-矩形交面积)
- hdu(1255)——覆盖的面积(线段树求面积交)
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
- HDU 1255 覆盖的面积(线段树求矩形面积交)
- hdu 1255 覆盖的面积 (线段树,离散化+扫描线)
- HDU 1255 覆盖的面积(线段树扫描线求面积的交)
- HDU-1255-覆盖的面积(线段树)
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- HDU 1255 覆盖的面积 线段树+扫描线