扫描线

传送出去吧

刚学了扫描线,这里仅仅想写写自己的思路,以我的表达水平,估计没人能听懂/(ㄒoㄒ)/~~
所以我贴里下面的链接供大家学习,个人感觉大佬讲的真很棒啊,讲出来很多别人没有的东西


大佬在这里哦


如果回来了的话,其实没有必要往下看了,嘿嘿……

表达我的理解

(简述离散化和线段树,主要是说扫描的思路与过程)

既然是要求矩形的面积并的话,很容易就想到都加起来然后减去重叠的部分,但也很显然写完人就挂了

如上图的矩形,当扫描线扫过时大概是一下这样的情况

这是就可以很显然的的把他分成3个小矩形(顺便假设几个坐标,然鹅画的并不均匀,所以改了改),如图

分完后再按每个原来矩形的左边的边和右边的边分别赋上 $ 1 $ 和 $ -1 $​ 的值,看看图

注意:一定是要原来矩形的,如图中绿色对应绿色,蓝色对应蓝色

当我们处理好以上这些时,就开始模拟一下了(注:一下所说的区间均是表示竖着的一条线段,如(10,30)表示第一条绿色的边)

我们可以根据纵坐标将整个图分成三个区间,每个区间初始值为0

此时\((10,15)=0,(15,30)=0,(30,37.5)=0\)

这里宽用\(kuan[i]\)表示,即\(kuan[1]=10,kuan[2]=10,kuan[3]=7.5\)

可以结合以下图片理解以下内容

从左往右开始扫描

遇到第一条边,这条边在(10,30)上为 \(1\) ,所以我们在这个区间上加 \(1\)

也就是\((10,15)+=1,(15,30)+=1\)

此时\((10,15)=1,(15,30)=1,(30,37.5)=0\)

当我们遇到第二条边的时候停下来(就是第一个矩形扫完了)开始计算

这时有贡献的边(区间值不为0的区间就有贡献)\((10,15)+(15,30)=(10,30)\)

所以第一个矩形的面积为\(kuan[1]*(30-10)=200\)

继续往右扫描

遇到第二条边(第一个矩形以这条边结束,第二个矩形以这条边开始),这条边在(15,37.5)上为 \(1\) ,所以在这个区间上加 \(1\)

\((15,30)+=1,(30,37.5)+=1\)

此时\((10,15)=1,(15,30)=2,(30,37.5)=1\)

当遇到第三条边停下(第二个矩形扫完了),开始计算

有贡献的边为\((10,15)+(15,30)+(30,37.5)=(10,37.5)\)

第二个矩形的面积为\(kuan[2]*(37.5-10)=275\)

继续往右扫描

遇到第三条边,这条边在(10,30)上为 \(-1\) ,所以在这个区间上减 \(1\)

\((10,15)-=1,(15,30)-=1\)

此时\((10,15)=0,(15,30)=1,(30,37.5)=1\)

当遇到第四条边停下(第三个矩形扫完了),开始计算

有贡献的边为\((15,30)+(30,37.5)=(15,37.5)\)

第三个矩形的面积为\(kuan[3]*(37.5-15)=168.75\)

继续往右扫

遇到第四条边,这条边在(15,37.5)上为 \(-1\) ,所以在这个区间上减 \(1\)

\((15,30)-=1,(30,37.5)-=1\)

此时\((10,15)=0,(15,30)=0,(30,37.5)=0\)

至此扫完了

最后的矩形面积为\(200+275+168.75=643.75\)


离散化

因为数据的范围很大会有负数会有小数

所以需要离散化

线段树

-----小水

里面的cover表示区间被覆盖的次数就是上面的每个区间的值(1,2,0,-1)

len就是kuan[i]

posted @ 2021-12-27 11:51  双枫  阅读(57)  评论(0编辑  收藏  举报