面积并

本质上是维护每个时间段里面数轴上有多少个点被赋值了
当题目数据到1e9 就需要离散化操作
统计数组上零的个数 维护最小值和最小值出现个数
然后判断下最小值是不是0

#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
#define pb(x) push_back(x)
using namespace std;
const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
const ll llinf =1e17+10;
const ll mod = 1e9+7;int val[maxn<<4];//记录区间最小值 在这里用于辅助维护0的个数
int sum[maxn<<4];//记录区间最小值出现的次数 用于统计0在整个区间出现的次数
int xbin[maxn*2];//记录x轴上的各端点
int ybin[maxn*2];//记录y轴上的各端点
int lz[maxn<<4];//lazytag标记数组
struct node
{int x1,x2,y1,y2;
}e[maxn];//记录正方形的四个端点struct point
{int x1,x2,v;
};//记录x轴上的边 下边记为1 即开始算本区域面积 上边记为0 即去除该区域标记vector<point>vec[maxn*2+10];//记录y=yi时 有多少区域是要被赋值的void pushup(int rt)//合并操作就是维护最小值及其出现次数
{if(val[lson]==val[rson]){val[rt]=val[lson];sum[rt]=sum[lson]+sum[rson];}else{int f=(val[lson]<val[rson])?lson:rson;val[rt]=val[f];sum[rt]=sum[f];}
}void pushdown(int rt)
{if(lz[rt]!=0){lz[lson]+=lz[rt];lz[rson]+=lz[rt];val[lson]+=lz[rt];val[rson]+=lz[rt];lz[rt]=0;}
}void build(int l,int r,int rt)
{lz[rt]=val[rt]=0;if(l==r){sum[rt]=xbin[l]-xbin[l-1];return;}int mid=(l+r)>>1;build(l,mid,lson);build(mid+1,r,rson);pushup(rt);
}void add(int rt,int L,int R,int l,int r,int v)
{if(L<=l&&r<=R){val[rt]+=v;lz[rt]+=v;return;}pushdown(rt);int mid=(l+r)>>1;if(L<=mid)add(lson,L,R,l,mid,v);if(R>mid)add(rson,L,R,mid+1,r,v);pushup(rt);
}int main()
{int n;scanf("%d",&n);int cntx=0,cnty=0;for(int i=1;i<=n;i++){scanf("%d%d%d%d",&e[i].x1,&e[i].y1,&e[i].x2,&e[i].y2);xbin[++cntx]=e[i].x1;xbin[++cntx]=e[i].x2;ybin[++cnty]=e[i].y1;ybin[++cnty]=e[i].y2;}//离散化操作sort(xbin+1,xbin+1+cntx);sort(ybin+1,ybin+1+cnty);cntx=unique(xbin+1,xbin+1+cntx)-xbin-1;cnty=unique(ybin+1,ybin+1+cnty)-ybin-1;//离散化后获取每个点在离散化数组中的下标for(int i=1;i<=n;i++){int x1=lower_bound(xbin+1,xbin+1+cntx,e[i].x1)-xbin;int x2=lower_bound(xbin+1,xbin+1+cntx,e[i].x2)-xbin;int y1=lower_bound(ybin+1,ybin+1+cnty,e[i].y1)-ybin;int y2=lower_bound(ybin+1,ybin+1+cnty,e[i].y2)-ybin;if(x1<x2){vec[y1].push_back((point){x1+1,x2,1});//这里用的是x1+1 而不是x1 可根据建树操作自行理解vec[y2].push_back((point){x1+1,x2,-1});}}//下面两行初始化 方便计算 切记放在build函数前ybin[0]=ybin[1];xbin[0]=xbin[1];build(1,cntx,1);ll ans=0;for(int i=1;i<=cnty;i++){//每次加边前计算面积int tem=sum[1];if(val[1]>0)tem=0;//最小值不是0就说明全部被赋值ll len=ybin[i]-ybin[i-1];ans+=len*(xbin[cntx]-xbin[1]-tem);for(int j=0;j<vec[i].size();j++){add(1,vec[i][j].x1,vec[i][j].x2,1,cntx,vec[i][j].v);}}printf("%lld\n",ans);
}

面积交

面积交例题
同样的区间覆盖,但是不能继续沿用上面统计0的方法来求,而是直接计算区间被覆盖的长度。
我们记录一个区间被覆盖的次数,如果大于等于2那么这个区间就会产生贡献。
区间合并的方法如下:
1.区间覆盖次数大于等于2时,那么这个区间的贡献就是这个区间的长度
2.区间覆盖次数等于1时,如果是叶子结点贡献为0,否则说明我们将这个区间全覆盖了1次,所以我们这个区间的贡献就是左区间被覆盖过的长度加上右区间被覆盖过的长度
3.区间覆盖次数等于0时,如果是叶子结点贡献为0,否则这个区间的贡献就是左区间被覆盖两次的长度加上右区间被覆盖两次的长度
我们合并的同时还需要合并该区间被覆盖的区间长度。

代码如下:


const int maxn = 2e3+10;
const int inf = 1e9+10;
const ll llinf =1e18+10;
const ll mod = 1e9+7;
const double pi = acos(-1);int val[maxn<<4];
pair<double,double> sum[maxn<<4];
double xbin[maxn*2];
double ybin[maxn*2];struct node
{double x1,x2,y1,y2;
}e[maxn];struct point
{int x1,x2,v;
};vector<point>vec[maxn*2+10];void pushup(int rt,int l,int r)
{if(val[rt]>=2)sum[rt].se=sum[rt].fi=xbin[r]-xbin[l-1];else if(val[rt]==1){sum[rt].fi=xbin[r]-xbin[l-1];if(l==r)sum[rt].se=0;elsesum[rt].se=sum[lson].fi+sum[rson].fi;}else{if(l==r)sum[rt].fi=sum[rt].se=0;else{sum[rt].se=sum[lson].se+sum[rson].se;sum[rt].fi=sum[lson].fi+sum[rson].fi;}}
}void build(int l,int r,int rt)
{val[rt]=0;sum[rt].fi=0;sum[rt].se=0;if(l==r){return;}int mid=(l+r)>>1;build(l,mid,lson);build(mid+1,r,rson);
}void add(int rt,int L,int R,int l,int r,int v)
{if(L<=l&&r<=R){val[rt]+=v;pushup(rt,l,r);return;}int mid=(l+r)>>1;if(L<=mid)add(lson,L,R,l,mid,v);if(R>mid)add(rson,L,R,mid+1,r,v);pushup(rt,l,r);
}int main()
{int _;scanf("%d",&_);while(_--){int n;scanf("%d",&n);int cntx=0,cnty=0;for(int i=1;i<=n;i++){scanf("%lf%lf%lf%lf",&e[i].x1,&e[i].y1,&e[i].x2,&e[i].y2);xbin[++cntx]=e[i].x1;xbin[++cntx]=e[i].x2;ybin[++cnty]=e[i].y1;ybin[++cnty]=e[i].y2;}sort(xbin+1,xbin+1+cntx);sort(ybin+1,ybin+1+cnty);cntx=unique(xbin+1,xbin+1+cntx)-xbin-1;cnty=unique(ybin+1,ybin+1+cnty)-ybin-1;for(int i=1;i<=n;i++){int x1=lower_bound(xbin+1,xbin+1+cntx,e[i].x1)-xbin;int x2=lower_bound(xbin+1,xbin+1+cntx,e[i].x2)-xbin;int y1=lower_bound(ybin+1,ybin+1+cnty,e[i].y1)-ybin;int y2=lower_bound(ybin+1,ybin+1+cnty,e[i].y2)-ybin;if(x1<x2){vec[y1].push_back((point){x1+1,x2,1});vec[y2].push_back((point){x1+1,x2,-1});}}ybin[0]=ybin[1];xbin[0]=xbin[1];build(1,cntx,1);double ans=0;for(int i=1;i<=cnty;i++){double tem=sum[1].se;double len=ybin[i]-ybin[i-1];ans+=len*(tem);for(int j=0;j<vec[i].size();j++){add(1,vec[i][j].x1,vec[i][j].x2,1,cntx,vec[i][j].v);}}printf("%.2f\n",ans);for(int i=1;i<=cnty;i++)vec[i].clear();}}

扫描线面积并、面积交模板相关推荐

  1. 223. 矩形面积(矩形面积并简单版)

    223. 矩形面积 (矩形面积并简单版) 两个矩形的面积并,可以用两矩形面积之和减去重叠部分面积. 关键在于求重叠面积,因为重叠部分也是矩形. 考虑分别向x,yx,yx,y轴投影. 求出两个投影长度, ...

  2. highcharts ajax 面积图,面积图及面积范围图 | Highcharts 使用教程

    面积图包括普通的面积图(area)及面积范围图(arearange),根据面积连接线的不同,又可以分为直线面积图(area.arearange)和曲线面积图(areaspline 及 areaspli ...

  3. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  4. HDU-1255 覆盖的面积 矩形面积交

    http://acm.hdu.edu.cn/showproblem.php?pid=1255 题义为给定N个矩形,求其重叠的图形面积,该题采用线段树离散化y轴坐标,并且采用分割思想,只依据x坐标来进行 ...

  5. hdu1828 线段树扫描线求矩形面积的周长

    题意:       给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路:       线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...

  6. POJ1151(线段树+扫描线求矩形面积并)

    题目:http://poj.org/problem?id=1151 #include <iostream> #include <string.h> #include <a ...

  7. python代码计算矩形面积_Python面积计算器源代码

    本程序通过一个while循环分两步计算图形面积,首先确认图形形状,然后根据不同的图形采用不同的面积公式进行计算,目前可支持矩形.正方形.三角形.梯形.圆形. 感兴趣的朋友还可以添加其它图形面积计算,也 ...

  8. matlab绘制星形线并求面积,星形线面积怎么求

    星形线面积求法:采用参数方程求面积.由于,星形线的面积关于坐标轴对称,因此,只需要求一个象限的面积. 星形线面积求法 星形线关于x轴和y轴对称的,如图,x=a(cost)^3,y=a(sint)^3 ...

  9. 标准正态分布面积(面积=比例=概率,不仅限于正态分布)

    对于一组数据,服从(均值0,标准差1)标准正态分布,的图形类似于: 对于标准正态分布来说,存在一张表,称为:标准正态分布表: 该表计算的是:P(X<=x)[某个数落在某个[-@,x]]的概率.也 ...

最新文章

  1. LNMP,PHP开启openssl,功能扩展,K哥
  2. oracle 11g数据库启动错误总结
  3. json相关,浏览器打开json格式的api接口时,进行格式化,chrome插件
  4. 数据科学 python_为什么需要以数据科学家的身份学习Python的7大理由
  5. mapreduce分组统计_mongodb中使用mapreduce进行分组统计
  6. php写cms,浅谈thinkPHP,国内写CMS利用率最高的框架
  7. 端口状态 LISTENING、ESTABLISHED、TIME_WAIT、FIN_WAIT_2、CLOSE_WAIT、CLOSE_WAIT
  8. python123第四章第五题_Python123
  9. ubuntu16.04 装机4:安装防火墙ufw
  10. 服务器芯片组 硒武,不到两个月的服务器,武器炼化出这属性是什么水平?
  11. 无线通信算法工程师知识地图
  12. Stimulsoft Reports 综合平台2019.x-2020.x
  13. 2017年第十七届迪培思广州国际广告展会刊(参展商名录)
  14. [KM 树同构Hash DP] BZOJ 3197 [Sdoi2013]assassin
  15. BIS新增手机测试认证标准 IS16333 (Part 3)2017.6.30 印度语
  16. python 描述性分析的包_pasty描述性统计包
  17. 智能路由器OpenWrt 开发环境 及 编译分析(一)
  18. Linux-根目录(/)的意义与内容
  19. 两年滴滴和头条的后端开发经验!字字都是肺腑之言!
  20. QtAndroid详解(2):startActivity和它的小伙伴们

热门文章

  1. (附源码)springboot掌上博客系统 毕业设计 063131
  2. python 习题练习二
  3. 《一战封神》(每日登录领礼包)做日环任务领剑魂
  4. BUUCTF wp-异性相吸
  5. 爬取网易云音乐热门歌曲热门评论
  6. 刷题日记【第十三篇】-笔试必刷题【数根+星际密码+跳台阶扩展问题+快到碗里来】
  7. HTML第三章 form表单(详解,内含详细代码示例)
  8. 【白帽优化大师】免费分享垃圾站截留别人网站流量技术
  9. 关闭windows或者windows server多用户会话
  10. 你的野花,朕的kibana