首页 > 其他分享 >扫描线-线段树

扫描线-线段树

时间:2022-11-01 12:15:01浏览次数:75  
标签:return val int 线段 long seg 扫描线 segment

求面积并

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

const int N=1e6+10;
int n;

int X[N*2];
struct segment
{
	int l,r,h,val;
}seg[N*2];

bool cmp(segment a,segment b)
{
	return a.h<b.h;
}

struct tree
{
	int l,r;
	int val;
	int len;
#define l(x) t[x].l
#define r(x) t[x].r
#define val(x) t[x].val
#define len(x) t[x].len
}t[N*4];

void pushup(int p)
{
	if(val(p)) len(p)=X[r(p)+1]-X[l(p)];
	else len(p)=len(p<<1)+len(p<<1|1);
}

void build(int p,int l,int r)
{
	l(p)=l,r(p)=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(p<<1,l,mid),build(p<<1|1,mid+1,r);
}

void update(int p,int l,int r,int val)
{
	if(l>=X[r(p)+1]||r<=X[l(p)]) return;
	if(l<=X[l(p)]&&r>=X[r(p)+1])
	{
		val(p)+=val;
		pushup(p);
		return;
	}
	update(p<<1,l,r,val);
	update(p<<1|1,l,r,val);
	pushup(p);
}

int main(){
	
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		X[2*i-1]=a,X[2*i]=c;
		seg[2*i-1]={a,c,b,1};
		seg[2*i]={a,c,d,-1};
	}
	n<<=1;
	sort(seg+1,seg+1+n,cmp);
	sort(X+1,X+1+n);
	int len=unique(X+1,X+1+n)-X-1;
	
	build(1,1,len-1);
	
	LL ans=0;
	for(int i=1;i<n;i++)
	{
		update(1,seg[i].l,seg[i].r,seg[i].val);
		ans+=(LL)len(1)*(LL)(seg[i+1].h-seg[i].h);
	}
	printf("%lld",ans);
	
	return 0;
}

求周长

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e4+10;
int n;

int X[N*2];
struct segment
{
	int l,r,h,val;
}seg[N];

bool cmp(segment a,segment b)
{
	if(a.h==b.h) return a.val>b.val;
	return a.h<b.h;
}

struct tree
{
	int l,r;
	int cov;
	int lc,rc;
	int val;
	int len;
	int cnt;
	
#define l(x) t[x].l
#define r(x) t[x].r
#define cov(x) t[x].cov
#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define val(x) t[x].val
#define len(x) t[x].len
#define cnt(x) t[x].cnt
	
}t[N*4];

void pushup(int p)
{
	if(cov(p))
	{
		lc(p)=rc(p)=1;
		len(p)=X[r(p)+1]-X[l(p)];
		cnt(p)=1;
	}
	else 
	{
		len(p)=len(p<<1)+len(p<<1|1);
		lc(p)=lc(p<<1),rc(p)=rc(p<<1|1);
		cnt(p)=cnt(p<<1)+cnt(p<<1|1);
		if(rc(p<<1)&&lc(p<<1|1)) cnt(p)--;
	}
}

void build(int p,int l,int r)
{
	l(p)=l,r(p)=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(p<<1,l,mid),build(p<<1|1,mid+1,r);
}
void update(int p,int l,int r,int val)
{
	if(l>=X[r(p)+1]||r<=X[l(p)]) return;
	if(l<=X[l(p)]&&r>=X[r(p)+1])
	{
		cov(p)+=val;
		pushup(p);
		return;
	}
	update(p<<1,l,r,val);
	update(p<<1|1,l,r,val);
	pushup(p);
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		seg[2*i-1]={a,c,b,1};
		seg[2*i]={a,c,d,-1};
		X[2*i-1]=a;
		X[2*i]=c;
	}
	
	n<<=1;
	sort(seg+1,seg+1+n,cmp);
	sort(X+1,X+1+n);
	int len=unique(X+1,X+1+n)-X-1;
	build(1,1,len-1);
	
	LL ans=0;
	int p=0;
	for(int i=1;i<n;i++)
	{
		update(1,seg[i].l,seg[i].r,seg[i].val);
		ans+=(LL)abs(p-len(1));
		ans+=(LL)2*cnt(1)*(LL)(seg[i+1].h-seg[i].h);
		p=len(1);
	}
	ans+=(LL)seg[n].r-seg[n].l;
	printf("%lld",ans);
	
	return 0;
}

标签:return,val,int,线段,long,seg,扫描线,segment
From: https://www.cnblogs.com/mrkou/p/16847238.html

相关文章

  • CF487E Tourists(Tarjan,圆方树,树链剖分,线段树)
    CF487ETourists带权无向图\(N,M\),\(Q\)次询问\(s,t\)所有不经过重复点可能路径经过的最小值的最小值。CODE每次修改一个圆点\(u\)周围的方点有点难。可是李神......
  • 线段树中递归
    楼房重建题目描述小A的楼房外有一大片施工工地,工地上有\(N\)栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少......
  • 【XSY4191】sequence(分块,线段树)
    题面sequence题解考虑把原序列每\(k\)位分成一段,然后对于每一段维护起点在这一段中的最小值。先考虑询问,对于起点在中间的整段我们直接线段树查区间最小值,现在考虑两......
  • 【XSY4041】搬砖(线段树)
    题面搬砖题解题意为求最大的\(p\)使得\(h_1\equivh_2\equiv\cdots\equivh_n\pmodp\)。即\(h_2-h_1\equivh_3-h_2\equiv\cdots\equivh_n-h_{n-1}\equiv0\pm......
  • P1803 凌乱的yyy / 线段覆盖
    题目背景快noip了,yyy很紧张!题目描述现在各大oj上有 nn 个比赛,每个比赛的开始、结束的时间点是知道的。yyy认为,参加越多的比赛,noip就能考的越好(假的)。所以......
  • 【XSY3810】公路建设(线段树,kruskal)
    题面题解一开始竟然没反应过来是最小生成树。考虑用线段树直接维护每个区间的答案。注意到一个区间最多只有\(n-1\)条树边有用,所以线段树每个节点用一个vector按权......
  • 【XSY3551】Inserting Lines(线段树)
    题意:数轴上有无穷个格子,每个坐标上各有一个格子,你需要支持以下操作共\(n\)次:在\(x=k\)这个格子前插入一个格子,并将所有\(x\geqk\)的格子后移一位。时间++。询问......
  • 【XSY3549】Tree(线段树,换根)
    原题不想说(太懒了),就说一下总结到的两点想法?对于树上多次询问路径信息的问题,如果两条路径的信息无法快速合并(即不能pushup),但是在路径两端增加/删除单点后的信息变化可以......
  • 基本线段树
    线段树P3372【模板】线段树1已知一个数列ai,有下列两种操作将区间[x,y]内每个数加上k求区间[x,y]中每个数的和线段树的思想便是将数列a,用若干个区间,在树上用结点表......
  • 【XSY3490】线段树(广义线段树,树上莫队)
    题面线段树题解本题分两Part走。Part1我们需要解决:如何在广义线段树上快速区间定位节点。对于有\(n\)个叶子节点、共\(2n-1\)个节点的广义线段树\(A\),我们......