HDU 1255 线段树扫描线面积交
来源:互联网 发布:成都卧龙大数据 苏明亮 编辑:程序博客网 时间:2024/04/27 23:20
题意:很多矩形会有重叠至少两次的地方,现在问重叠至少两次的面积。
想法:线段树扫描线,对于一个区间[x,y],用cover表示这个区间整体被覆盖的次数,用one表示这个区间只被覆盖一次的长度,more表示这个区间被覆盖至少两次的长度。用seglen表示这个区间的长度,那么one+more=seglen,下面我们来讨论他们的关系。
1.cover>=2:表示这个区间已经被至少覆盖了两次,显然是我们要求的,所以直接把长度推上去。
2.cover=1:表示这个区间已经被覆盖正好一次,显然我们可以想到在这个区间内,可能存在有一部分存在覆盖两次的情况,因为cover表示的是整个区间的覆盖情况,并不能表示细节。所以这个区间要询问他的左右孩子,只要他们至少被覆盖一次,那么就可以算上,因为这个区间本身就已经有了一次覆盖了。
3.cover=0:表示这个区间没有被覆盖,显然有可能有一部分是有覆盖情况的,所以需要询问他的左右孩子。
以上就是面积交的pushup函数的主要思想了。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define LL(x) x<<1#define RR(x) x<<1|1using namespace std;const int nodes=1005;int n;struct node{ double l,r,h; int f;}bian[nodes*2];struct nodee{ int lft,rht; int cover; double more,one; int mid() { return (lft+rht)/2; }};double pos[nodes*2];bool cmp(node a,node b){ return a.h<b.h;}int bin_search(double num,int l,int r){ while(l<=r) { int mid=(l+r)/2; if(pos[mid]==num) return mid; else if(pos[mid]<num) { l=mid+1; } else r=mid-1; } return -1;}class Seg{ public: nodee tree[nodes*8]; void get_len(int index) { if(tree[index].cover>=2) { tree[index].more=tree[index].one=pos[tree[index].rht+1]-pos[tree[index].lft]; } else if(tree[index].cover==1) { tree[index].one=pos[tree[index].rht+1]-pos[tree[index].lft]; if(tree[index].lft==tree[index].rht) tree[index].more=0; else tree[index].more=tree[LL(index)].one+tree[RR(index)].one; } else { if(tree[index].lft==tree[index].rht) tree[index].more=tree[index].one=0; else { tree[index].more=tree[LL(index)].more+tree[RR(index)].more; tree[index].one=tree[LL(index)].one+tree[RR(index)].one; } } } void build(int lft,int rht,int index) { tree[index].lft=lft; tree[index].rht=rht; tree[index].more=0; tree[index].one=0; tree[index].cover=0; if(lft!=rht) { int mid=tree[index].mid(); build(lft,mid,LL(index)); build(mid+1,rht,RR(index)); } } void updata(int s,int t,int val,int index) { int lft=tree[index].lft; int rht=tree[index].rht; if(s<=lft&&rht<=t) { tree[index].cover+=val; get_len(index); return; } int mid=tree[index].mid(); if(s<=mid) updata(s,t,val,LL(index)); if(t>mid) updata(s,t,val,RR(index)); get_len(index); }}seg;int main(){ int ca=1; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); int cnt=0,cnt1=1; for(int i=1;i<=n;i++) { double a,b,c,d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); pos[cnt]=a;bian[cnt].l=a;bian[cnt].r=c;bian[cnt].h=b;bian[cnt].f=1; pos[cnt+1]=c;bian[cnt+1].l=a;bian[cnt+1].r=c;bian[cnt+1].h=d;bian[cnt+1].f=-1; cnt+=2; } sort(pos,pos+cnt); sort(bian,bian+cnt,cmp); for(int i=1;i<cnt;i++) { if(pos[i]!=pos[i-1]) { pos[cnt1++]=pos[i]; } } double sum=0; seg.build(0,cnt1-1,1); for(int i=0;i<cnt-1;i++) { int l=bin_search(bian[i].l,0,cnt1-1); int r=bin_search(bian[i].r,0,cnt1-1)-1; seg.updata(l,r,bian[i].f,1); double hh=seg.tree[1].more; sum+=(bian[i+1].h-bian[i].h)*hh; } printf("%.2lf\n",sum); } return 0;}
0 0
- 【线段树 && 扫描线 && 面积交】HDU
- HDU 1255 线段树扫描线面积交
- HDU 1255 - 覆盖的面积 (线段树 扫描线 面积交)
- HDU 1255 覆盖的面积(线段树扫描线求面积的交)
- HDU 1255 覆盖的面积 (线段树扫描线+面积交)
- hdu 1255 覆盖的面积(线段树+扫描线——面积交)
- hdu 1542 矩形面积并 &&hdu 1255 矩形面积交 && hdu 1828 矩阵周长并 线段树+扫描线入门
- hdu 1255 线段树+离散化+扫描线 (矩形面积交
- HDU 1255(线段树,扫描线,矩形的面积交)
- HDU3265 Posters(线段树+扫描线——面积交)
- hdu 1542 ,1255 线段树面积并与面积交
- HDU 1255 覆盖的面积(线段树+面积交)
- 【线段树 面积并 扫描线】HDU
- HDU 1255 覆盖的面积 线段树 扫描线
- 线段树 扫描线 HDU 1255 覆盖的面积
- HDU-1255 覆盖的面积 线段树 + 扫描线
- hdu 1255 覆盖的面积 线段树扫描线num2
- 【HDU】1255 覆盖的面积 线段树+扫描线
- JavaScript调试技巧之console.log()详解
- 栈-Implement Stack using Queues(用队列实现栈)
- 靠给员工画大饼,一口气创办10家公司 他的创业模式吓坏大佬!
- Excel打开csv文件分列问题
- 解压版/免安装版MySQL配置全解
- HDU 1255 线段树扫描线面积交
- easyui 加载
- TransformException: com.android.ide.common.process.ProcessException:错误解决
- 图解DHCP的4步租约过程
- Kinect for Unity V2 代码示例(三) 手势控制
- 穷游Q-Home:看脸,是文艺范的“一日游”地接社
- 《聊聊Socket、TCP/IP、HTTP、FTP及网络编程》 / 《聊聊同步、异步、阻塞与非阻塞》
- 【自定义标签开发】08-标签案例-开发if..else标签
- log4j2 配置 基于JAVA 以Web为例