The tree outside the school gate (merge interval, line segment tree)

insert image description here
https://www.luogu.com.cn/problem/P1047

Thought analysis:

Because only one query is needed in the end, an intuitive idea is to combine all the intervals and subtract the interval length from the total.
The key is how to combine the ranges. This may not be easy to think about and requires some thinking. The overall time complexity O(nlgn)
merge interval can refer to this blog:
https://blog.csdn.net/Skyed_blue/article/details/109467628

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

struct node{
    
    
	int l, r;
};

bool cmp(const node &a, const node &b)
{
    
    
	return a.l < b.l;
}

int main()
{
    
    
	node t, arr[105];
	int n, m;
	scanf("%d%d",&n,&m);
	n++;
	for(int i = 0;i < m;i++)
	{
    
    
		int l, r;
		scanf("%d%d",&l,&r);
		arr[i] = {
    
    l,r};
	}
	sort(arr,arr+m,cmp);
	t = arr[0];
	for(int i = 1;i < m;i++)
	{
    
    
		if(arr[i].l <= t.r) t.r = max(arr[i].r,t.r);
		else n -= t.r-t.l+1, t = arr[i];
	}
	n -= t.r-t.l+1;
	cout<<n<<endl;
	return 0;
}

The second method is the brainless segment tree. To maintain an interval sum as the number of the interval value of 1, the problem can be regarded as multiple interval sum updates and one interval sum query. Note that if there is an interval [0,1,1], the interval sum is 2. To update this interval the final interval sum is 0 instead of -1. So every interval update and 0 compare the size.

#include <iostream>
#include <cstdio>
using namespace std;

const int MAX = 10010;
struct node{
    
    
	int l, r, val, lazy;
}T[MAX<<2];

//维护一个区间个数的线段树 

void pushup(int rt)
{
    
    
	T[rt].val = T[rt<<1].val+T[rt<<1|1].val;
}

void pushdown(int rt)
{
    
    
	if(T[rt].lazy)
	{
    
    
		int x = rt<<1, y = rt<<1|1;
		T[x].val += (T[x].r-T[x].l+1)*T[rt].lazy;
		T[x].val = max(T[x].val,0);
		T[y].val += (T[y].r-T[y].l+1)*T[rt].lazy;
		T[y].val = max(T[y].val,0);
		T[x].lazy += T[rt].lazy;
		T[y].lazy += T[rt].lazy;
		T[rt].lazy = 0;
	}
}

void build(int rt, int L, int R)
{
    
    
	T[rt].l = L, T[rt].r = R, T[rt].val = 0, T[rt].lazy = 0;
	if(L == R)
	{
    
    
		T[rt].val = 1;
		return;
	}
	int mid = L+R>>1;
	build(rt<<1,L,mid);
	build(rt<<1|1,mid+1,R);
	pushup(rt);
}

void update(int rt, int L, int R, int x)
{
    
    
	if(L <= T[rt].l && R >= T[rt].r)
	{
    
    
		T[rt].val += (T[rt].r-T[rt].l+1)*x;
		T[rt].val = max(T[rt].val,0);
		T[rt].lazy += x;
		return;
	}
	pushdown(rt);
	int mid = T[rt].l+T[rt].r>>1;
	if(L <= mid) update(rt<<1,L,R,x);
	if(R > mid) update(rt<<1|1,L,R,x);
	pushup(rt);
}

int Query(int rt, int L, int R)
{
    
    
	if(L <= T[rt].l && R >= T[rt].r)
	{
    
    
		return T[rt].val;
	}
	pushdown(rt);
	int mid = T[rt].l+T[rt].r>>1;
	int x1 = 0, x2 = 0;
	if(L <= mid) x1 = Query(rt<<1,L,R);
	if(R > mid) x2 = Query(rt<<1|1,L,R);
	return x1+x2;
}


int main()
{
    
    
	int n, m;
	scanf("%d%d",&n,&m);
	build(1,1,n+1);
	while(m--)
	{
    
    
		int L, R;
		scanf("%d%d",&L,&R);
		update(1,L+1,R+1,-1);
	}
	int ans = Query(1,1,n+1);
	cout<<ans<<endl;
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325715095&siteId=291194637