首页 > 其他分享 >扫描线

扫描线

时间:2022-11-14 00:00:09浏览次数:70  
标签:10 ch int le 扫描线 include

扫描线

摆烂了 \(3++\) 月后,开始学习(复习)的第一个知识点,顺便复习下 \(markdown\)

再顺便转到博客园,不定时把博客 \(luogu->cnblogs\)

原题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)\)。

输出格式

一行一个正整数,表示 \(n\) 个矩形的并集覆盖的总面积。

样例 #1

样例输入 #1

2
100 100 200 200
150 150 250 255

样例输出 #1

18000

提示

对于 \(20\%\) 的数据,\(1 \le n \le 1000\)。
对于 \(100\%\) 的数据,\(1 \le n \le {10}^5\),\(0 \le x_1 < x_2 \le {10}^9\),\(0 \le y_1 < y_2 \le {10}^9\)。

好吧,没啥好说的,注意一下离散化的细节问题,建树里面的 \(n\) 要带 \(tot-1\),debug了好久,恼(误

上代码

#include <cstdio>
#include <algorithm>
#include <iostream>
#define int long long
const int maxn = 1e6+10;
using namespace std;
int n,cnt = 0;
int x1,x2,y1,y2,X[maxn<<1];
int read()
{
	int x = 0,f = 1;char ch = getchar();
	while(ch < '0'||ch > '9'){if(ch == '-') f = -1;ch = getchar();}
	while(ch >= '0'&&ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
	return x*f;
}
struct Scanline{
	int l,r,h;
	int mark;
	bool operator < (const Scanline &x)const{
		return h < x.h;
	}
}line[maxn << 1];
int sum[maxn<<2],len[maxn<<2];
void build(int p,int l,int r)
{
	len[p] = 0;
	sum[p] = 0;
	if(l == r) return;
	int mid = l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
}
void pushup(int p,int l,int r)
{
	if(sum[p]) len[p] = X[r+1] - X[l];
	else len[p] = len[p<<1]+len[p<<1|1];
}
void modify(int p,int l,int r,int L,int R,int c)
{
	if(X[r+1]<=L || X[l]>=R) return;
	if(L <= X[l]&&X[r+1] <= R)
	{
		sum[p]+=c;
		pushup(p,l,r);
		return;
	}
	int mid = l+r>>1;
	modify(p<<1,l,mid,L,R,c);
	modify(p<<1|1,mid+1,r,L,R,c);
	pushup(p,l,r);
}
signed main()
{
	n = read();
	for(int i = 1;i <= n;i++)
	{
		x1 = read(),y1 = read(),x2 = read(),y2 = read();
		//printf("%lld-%lld-%lld-%lld\n",x1,y1,x2,y2);
		X[2*i-1] = x1;
		X[2*i] = x2;
		line[2*i-1] = (Scanline){x1,x2,y1,1};
		line[2*i] = (Scanline){x1,x2,y2,-1};
	}
	n<<=1;
	sort(line+1,line+n+1);
	sort(X+1,X+n+1);
	int tot = unique(X+1,X+n+1) - X - 1;

	build(1,1,tot-1);
	int ans = 0;
	for(int i = 1;i < n;i++)
	{
		modify(1,1,tot-1,line[i].l,line[i].r,line[i].mark);//tot-1注意 
		ans += len[1]*(line[i+1].h-line[i].h);
	}
	printf("%lld",ans);
	return 0;
}

标签:10,ch,int,le,扫描线,include
From: https://www.cnblogs.com/asdfo123/p/16887765.html

相关文章

  • 【学习笔记】扫描线
    备战NOIP2022填坑ing...扫描线思想就是把横边从小到大sort,拿条线从下往上扫,扫到横边算一下长度,再乘上两条横边的高度差,因为要求\(O(nlogn)\)的时间复杂度所以用线段......
  • 扫描线-线段树
    求面积并#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e6+10;intn;intX[N*2];structsegment{ intl,r,h,val;}seg[N*2]......
  • 【XSY3479】子区间(扫描线)
    题意:转化后变为:平面上给定\(n\)个关键点,\(q\)次询问一个点与其左上的每个关键点形成的矩形面积的最大值。题解:挺玄妙的一题。这里假设这\(n\)个关键点都是\(x\)......
  • 【BZOJ1818】【CQOI2010】【XSY2428】内部白点(树状数组+扫描线)
    先把所有点的\(x\)坐标离散化。然后分别将所有点按\(x\)、\(y\)排序。这里以按\(x\)排序为例,对于\(x\)坐标相同的两个点,我们把它们连成一条线段。那么按\(y\)坐标排序也一......
  • 扫描线
    P5816[CQOI2010]内部白点//结论:最多进行一次变色过程//推论:不会输出-1证明:反证//本题做法:扫描线//只计算横坐标相同,纵坐标相邻//与纵坐标相......
  • 【综合笔试题】难度 4.5/5,扫描线的特殊运用(详尽答疑)
    ​题目描述这是LeetCode上的218.天际线问题,难度为困难。Tag:「扫描线问题」、「优先队列(堆)」城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给......
  • uva688 (扫描线)
    AmobilephonecompanyACMICPC(AdvancedCellular,Mobile,andInternet-ConnectedPhoneCorporation)isplanningtosetupacollectionofantennasformobileph......
  • AcWing 算法提高课 线段树+扫描线法 求矩形之并的面积
    例题:求解多个长方形之并的面积https://www.acwing.com/problem/content/249/蓝色表示长方形,红色表示扫描线如下图所示,对于每一个横向的区间,在纵向维护线段树根据纵向......
  • 矩形面积并(扫描线)
      思路:扫描线的思路很容易确定,但难点在于如何实现。这里避免写持久化标记,最初的想法是记录区间内0的个数(即未覆盖点的个数),但是如此一来每一次更新都需要将tag下放到最......
  • 浅谈扫描线
    准备学习扫描线的时候,发现洛谷日报上并没有关于扫描线的文章,于是心血来潮想写一篇。顺便纪念一下我马上结束的OI生涯。前置知识线段树或树状数组(不会的请【模板】线......