hdu1255 矩形面积二次交
来源:互联网 发布:windows 会员如何加入 编辑:程序博客网 时间:2024/05/17 03:52
http://acm.hdu.edu.cn/showproblem.php?pid=1255
理解hdu1542后,这题也就改一下就行了。
题意:给出n个矩形的左下角与右上角坐标,求矩形覆盖两次以上的面积
解题思路:
与hdu1542思路一样,将X坐标离散建树再一层一层计算面积,唯一不同在于这里多一个量twoMoreLen,向上更新时维护好twoMoreLen就好
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<iostream>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<bitset>using namespace std;#define N 1100struct line{ double left,right,h; int flag;}L[2*N];map<double,int>M;double X[2*N];double XLi[2*N];int cmp(line aa,line bb){ return aa.h<bb.h;}struct node{ int left,right,cover;//cover表示该段成段覆盖的次数,但不向下更新 double oneMoreLen,twoMoreLen;//该区间覆盖一次以上、两次以上的长度}seg_tree[N*4];void seg_built(int l,int r,int num){ seg_tree[num].left=l; seg_tree[num].right=r; seg_tree[num].cover=0; seg_tree[num].oneMoreLen=0; seg_tree[num].twoMoreLen=0; if(r!=l+1) { int mid=(l+r)>>1; seg_built(l,mid,num<<1); seg_built(mid,r,num<<1|1); }}void push_up(int num)//向上更新{ if(seg_tree[num].cover>=2) { seg_tree[num].twoMoreLen=XLi[seg_tree[num].right]-XLi[seg_tree[num].left]; seg_tree[num].oneMoreLen=XLi[seg_tree[num].right]-XLi[seg_tree[num].left]; return; } if(seg_tree[num].cover==1) { if(seg_tree[num].right==seg_tree[num].left+1)//叶子节点 { seg_tree[num].twoMoreLen=0; seg_tree[num].oneMoreLen=XLi[seg_tree[num].right]-XLi[seg_tree[num].left]; } else//非叶子节点,twoMoreLen要看下面的oneMoreLen长度 { seg_tree[num].twoMoreLen=seg_tree[2*num].oneMoreLen+seg_tree[2*num+1].oneMoreLen; seg_tree[num].oneMoreLen=XLi[seg_tree[num].right]-XLi[seg_tree[num].left]; } return; } if(seg_tree[num].right==seg_tree[num].left+1) { seg_tree[num].oneMoreLen=0; seg_tree[num].twoMoreLen=0; } else { seg_tree[num].oneMoreLen=seg_tree[2*num].oneMoreLen+seg_tree[2*num+1].oneMoreLen; seg_tree[num].twoMoreLen=seg_tree[2*num].twoMoreLen+seg_tree[2*num+1].twoMoreLen; }}void seg_update(int l,int r,int value,int num){ if(l>=seg_tree[num].right||r<=seg_tree[num].left) return; if(l<=seg_tree[num].left&&r>=seg_tree[num].right) { seg_tree[num].cover+=value; push_up(num); return; } seg_update(l,r,value,2*num); seg_update(l,r,value,2*num+1); push_up(num);}int main(){ int i,j,k; int n,m,t; scanf("%d",&t); while(t--) { scanf("%d",&n); M.clear(); m=0; for(i=1;i<=n;i++) { double x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); X[++m]=x1; L[m].left=x1; L[m].right=x2; L[m].h=y1; L[m].flag=1;//线段记录 X[++m]=x2; L[m].left=x1; L[m].right=x2; L[m].h=y2; L[m].flag=-1;//线段记录 } sort(X+1,X+1+m); sort(L+1,L+1+m,cmp); M[X[1]]=1; XLi[1]=X[1]; j=1; for(i=2;i<=m;i++)//X坐标离散化 { if(X[i]!=X[i-1]) { M[X[i]]=++j; XLi[j]=X[i]; } } seg_built(1,j,1); double sum=0; for(i=1;i<m;i++) { seg_update(M[L[i].left],M[L[i].right],L[i].flag,1); sum+=seg_tree[1].twoMoreLen*(L[i+1].h-L[i].h); } printf("%.2lf\n",sum); }}/*input:251 1 4 21 3 3 72 1.5 5 4.53.5 1.25 7.5 46 3 10 730 0 1 11 0 2 12 0 3 1output:7.630.00*/
0 0
- hdu1255 矩形面积二次交
- 【HDU1255】覆盖的面积【线段树】【矩形面积交】
- hdu1255 覆盖的面积(矩形面积交+扫描线)
- hdu 1255 覆盖的面积(矩形面积二次交)
- 【hdu1255】覆盖的面积(矩形面积交+线段树+扫描线)
- HDU1255 覆盖的面积(线段树,离散化,扫描线,矩形面积交)
- hdu1255(线段树求面积交)
- 矩形面积交
- 11.矩形面积交
- 矩形面积交---蓝桥杯
- 矩形面积交
- 矩形面积交
- 矩形面积交
- 矩形面积交
- 蓝桥杯 矩形面积交
- 矩形面积交
- 矩形面积交
- 矩形面积交
- xcod architecture 设置解释
- oracle数据库链路的创建和使用
- C++数组作为函数参数的几个问题
- python过滤html 标签
- java调用CICS服务遇到的错误及解决方法
- hdu1255 矩形面积二次交
- 机器人破解注册原理
- 本地通知
- 九度OJ 1007 奥运排序问题
- ARM全新Cortex-A17定位中端,主频2G
- Java 7之多线程第8篇 - 互斥锁 ReentrantLock
- c# dataset保存多属性的XML
- linux iptables
- 程序员如何快速准备面试中的算法