線段樹練習題四
題目
在平面內有一條長度爲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;
}