【線段樹】線段樹練習題四

線段樹練習題四

題目

在平面內有一條長度爲n的線段(不計入答案),可以對進行以下2種操作:
1、把從x到y的再加一條線段
2、查詢從x到x+1有多少條線段

輸入

第一行輸入n,m
第2~m+1行,每行2個數x,y,表示從x到y再加一條線段
最後一行輸入2個數,爲x和x+1,查詢x到x+1的線段數目

輸出

輸出x到x+1的線段數目

輸入樣例

7 2
2 5
3 6
4 5

輸出樣例

2

數據範圍

100%滿足1≤n≤100000,1≤x≤y≤n

解題思路

其實這道題就是一道線段樹(emmm…看題目就知道了 ),其實就是先建好一棵樹後,然後統計每個區間有多少線即可.

程序如下

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,x,y,xx,yy;

struct r
{
	int l,r,sum;
}tree[400001];

void Build(int x,int l,int r)//建樹
{
    tree[x].l = l;
	tree[x].r = r; 
	if(l + 1 >= r) return ;
	int mid = (l + r) / 2;
	Build(x * 2,l,mid);
	Build(x * 2 + 1,mid,r);
}

void insert(int x,int l,int r)//插入所在區間
{
	int mid = (tree[x].l + tree[x].r) / 2;
	if(tree[x].l == l && tree[x].r == r) 
	   tree[x].sum++;
	else if(r <= mid) insert(x * 2,l,r);
	else if(l >= mid) insert(x * 2 + 1,l,r);
	else 
	{
		insert(x * 2,l,mid);
		insert(x * 2 + 1,mid,r);
	}
}

int tj(int x,int l,int r)//統計
{
	int ans = tree[1].sum;
	while(tree[x].l + 1 < tree[x].r)
	{
		int mid = (tree[x].l + tree[x].r) / 2;
		if(tree[x].l == l && tree[x].r == r) break;
		else if(r <= mid) 
		{
			x *= 2;
			ans += tree[x].sum;
		}
		else if(l >= mid)
		{
			x *= 2;
			x++;
			ans += tree[x].sum;
		}
	}
	return ans;
}

int main()
{
	scanf("%d%d",&n,&m);
	Build(1,1,n);
	for(int i = 1;i <= m; ++i)
	{
		scanf("%d%d",&x,&y);
		insert(1,x,y);
	} 
	scanf("%d%d",&xx,&yy);
	printf("%d",tj(1,xx,yy));
	return 0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章