首页 > 其他分享 >扫描线

扫描线

时间:2023-09-10 16:44:37浏览次数:35  
标签:int y1 maxn 扫描线 x2 x1

#include<bits/stdc++.h>
#define maxn 200005
#define int long long
using namespace std;
int x[maxn];//x[i]表示从左往右第i条竖边
int tsum[maxn<<3],tlen[maxn<<3];
//tsum表示当前节点被覆盖的次数
//tlen是当前节点所对应的长方形的长 

void pushup(int k,int l,int r)//tsum是由+1-1决定的,所以只更新tlen 
{
	if(tsum[k]) tlen[k] = x[r+1]-x[l];
	//若整个区间都被访问过了则tlen为对应的区间长度
	else tlen[k] = tlen[k<<1]+tlen[k<<1|1];
	//否则为左右节点的长方形长之和 
}

struct node{
	int l,r,h,v;
}y[maxn];

bool cmp(node x, node y)
{
	return x.h<y.h;
}

void updata(int k,int l,int r,int L,int R,int v)
{
	//LR指的是实际区间而不是x的下标
	//lr指的是x的实际下标范围 
	if(L <=x[l] && x[r+1]<=R)//如果在区间内就直接更新tsum
	{
		tsum[k] += v;
		pushup(k,l,r);//更新tlen,因为tlen也是受tsum影响的 
		return;
	} 
	int m = l + ((r-l)>>1);
	if(l < x[m+1])
		updata(k<<1,l,m,L,R,v);
	//与一般的线段树不同,更新[1,3],不用更新[3,4]这个区间,故不用取等
	//时刻注意区间[l,m]对应x的范围是[l,m+1]
	if(R>x[m+1])
		updata(k << 1 | 1, m + 1, r, L, R, v);
	pushup(k,l,r);
		 
}

signed main()
{
	int n;
	cin>>n;
	for(int i = 1;i<=n;i++)
	{
		int x1,y1,x2,y2;
		cin>>x1>>y1>>x2>>y2;
		//先纵坐标后横坐标 
		x[2*i-1] = x1;
		x[2*i] = x2;
		y[2*i-1] = {x1,x2,y1,1};
		y[2*i] = {x1,x2,y2,-1};
	}
	sort(y+1,y+1+2*n,cmp);
	sort(x+1,x+1+2*n);
	int len = unique(x+1,x+1+2*n)-x-1,ans = 0;//去重 
	for(int i = 1;i <2*n;i++)
	{
		updata(1,1,len-1,y[i].l,y[i].r,y[i].v);
		//len-1因为对应的是“左端点” 
		ans+=tlen[1]*(y[i+1].h-y[i].h);
		//宽度是下一条边高度减去当前高度 
	}
	cout<<ans;
	return 0;
}

标签:int,y1,maxn,扫描线,x2,x1
From: https://www.cnblogs.com/narcissusyl/p/17691463.html

相关文章

  • 扫描线补充
    1.两条扫描线之间,不一定是一个矩形,可能是多个不相交的,高相同的矩形2.扫描线的板子没有pushdownvoidupd(intu,intl,intr){ if(cnt[u]){ len[u]=b[r+1]-b[l]; sum[u]=2; lh[u]=rh[u]=1; }else{ len[u]=len[lch]+len[rch]; sum[u]=sum[lch]+sum[rch]; lh[u]=lh[......
  • P5490 【模板】扫描线
    \(P5490\)【模板】扫描线一、题目描述求\(n\)个四边平行于坐标轴的矩形的面积并。输入格式第一行一个正整数\(n\)。接下来\(n\)行每行四个非负整数\(x_1,y_1,x_2,y_2\),表示一个矩形的四个端点坐标为\((x_1,y_1),(x_1,y_2),(x_2,y_2),(x_2,y_1)\)。输出格式......
  • 【单调队列】 单调队列的“扫描线”理解
    【单调队列】单调队列的“扫描线”理解  “如果一个选手比你小还比你强,你就可以退役了。”——单调队列的原理比你强,而且比你影响时间更长。某种意义上,数学思维是生活中的思考的延伸。  算法学习笔记(66):单调队列。引用Pecco的算法笔记。  在这里给出一种扫描线......
  • 扫描线学习笔记
    0.写在前面扫描线好闪,拜谢扫描线1.问题的引入在一个二维的坐标系上,给出多个矩形,求他们的面积并2.问题的分析假设我们有这么一张图你要求这三个矩形的面积并,可以考虑容斥原理,但这样会TLE但总之,他最终的结果是围成了一个多边形那你不妨考虑,重新分割这个最终的图形那......
  • 「学习笔记」扫描线
    什么是扫描线?顾名思义,一根用来扫描的线扫描线就是一条线在整个图上扫来扫去,它一般被用来解决图形面积,周长,以及二维数点等问题。下面我们用例题来引入。P5490【模板】扫描线-洛谷|计算机科学教育新生态(luogu.com.cn)我们对于这种题有三种做法暴力的进行覆盖扫描容......
  • [Ynoi2012] NOIP2015 充满了希望(扫描线+线段树)
    题目传送门solution简单题。我们正着做扫描线。设\(t_i\)表示位置\(i\)最后一次进行二操作的时间,那么一操作就是交换\(t_x,t_y\),二操作就是区间复制。对于三操作,开一个树状数组,如果查询的位置的\(t_x=j\),就在\(j\)的位置上加一。查询就是查询后缀和。#include<bit......
  • [Ynoi Easy Round 2021] TEST_152(颜色段数均摊+扫描线)
    题目传送门solution简单题,考虑正着做扫描线,维护最后一次覆盖每个位置的修改时间,这个可以用\(set\)维护颜色段数均摊。那么显然对于一个以当前位置为右端点的询问,其答案就是所有最后修改时间大于等于左端点的位置的数的和。开一个树状数组维护最后一次修改时间是\(i\)的位......
  • 【学习笔记】扫描线
    扫描线是用来求解图形面积并的一个算法。问题引入给定\(n\)个长方形,求它们的面积并。下面以两个长方形为例:对于这个问题,可以有容斥等做法,但是还有个更简单的方法——扫描线。扫描线扫描线,顾名思义,就是,拿一条“线”取扫(这里是从下往上扫,其实其它的扫的方式也是可以的):如图......
  • 【学习笔记】扫描线
    【别急,我也不会,没写完】目录定义:例题(解释):定义:如图:(图片来源:oiwiki)像这样的一条线在图上扫描时,便是扫描线。(呃呃和没说没有任何区别呢)因此可见扫面线往往是求矩形面积并集或周长并集的好工具,当然,也可以运用在二维图中。当然它不止可以从上往下扫,还可以从左往右扫:(当然自己......
  • 扫描线Manhattan Distance
    ProblemC.ManhattanDistance主要算法:扫描线二分来源:XIIISamaraRegionalIntercollegiateProgrammingContestRussia,Samara,March29,2020题意:给你二维平面上的n个点,每个点之间都存在一个曼哈顿距离,要求你求出第k小的曼哈顿距离\((2\leqn\leq100000)\)假如你......