线段树练习题一 SSL 2644
Description–
桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如右图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少? (俯视图)
Input–
第1行:桌面总宽度n
第2行:盒子数量m
第3 ~ m+2行:盒子的左端,盒子的右端
Output–
一个整数ans
Sample Input–
20
4
1 5
3 8
7 10
13 19
Sample Output–
15
说明–
1<=n<=100000,1<=m<=100000,保证坐标范围为[1,n].
代码–
#include<iostream>
#include<cstdio>
using namespace std;
int n, m, x, y, t = -1;
bool tree[400005];
void ist(int z, int l, int r, int xx, int yy)
{
if (tree[z]) return ;
if (l == xx && r == yy)
{
tree[z] = 1;
return ;
}
int mid = (l + r) / 2;
if (xx <= mid) ist(2 * z, l, mid, xx, min(mid, yy));
if (yy > mid) ist(2 * z + 1, mid + 1, r, max(mid + 1, xx), yy);
}
int find(int z, int l, int r)
{
if (tree[z])
{
int ans = r - l;
if (l == t + 1) ans++;
t = r;
return ans;
}
if (l == r)
return 0;
int mid = (l + r) / 2;
return find(2 * z, l, mid) + find(2 * z + 1, mid + 1, r);
}
int main()
{
scanf("%d%d", &n,&m);
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &x,&y);
ist(1, 1, n, x, y);
}
printf("%d", find(1, 1, n));
return 0;
}