桌子上零散地放着若干個盒子,桌子的後方是一堵牆。如右圖所示。現在從桌子的前方射來一束平行光, 把盒子的影子投射到了牆上。問影子的總寬度是多少?
20
4
1 5
3 8
7 10
13 19
15
數據範圍
1<=n<=100000,1<=m<=100000,保證座標範圍爲[1,n].
線段樹
定義一個參數cover,用於表示當前區間是否被完全覆蓋
統計時,計算被覆蓋的區間大小就好了
#include<iostream>
#include<cstdio>
using namespace std;
int ans;
struct Tree
{
int l, r;
bool cover;
}tree[400005];
void Build(int x, int L, int R)
{
tree[x].l = L; tree[x].r = R;aasds
if (tree[x].l >= tree[x].r) return;
int mid = (tree[x].l + tree[x].r) >> 1;
Build(x * 2, L, mid);
Build(x * 2 + 1, mid + 1, R);
}//建樹
void Ins(int x, int L, int R)
{
if (tree[x].cover == 1) return;
if (tree[x].l == L && tree[x].r == R)
{
tree[x].cover = 1;w
return ;
}
if (tree[x].l >= tree[x].r) return ;
int mid = (tree[x].r + tree[x].l) >> 1;
if (R <= mid) Ins(x * 2, L, R);//查詢左子節點
else if (L > mid) Ins(x * 2 + 1, L, R);//查詢右子節點
else {
Ins(x * 2, L, mid);
Ins(x * 2 + 1, mid + 1, R);//兩邊的節點都有的情況
}
}//插入
void Count(int x)
{
if (tree[x].cover == 1) {
ans += (tree[x].r - tree[x].l + 1);
return ;
}
if (tree[x].l >= tree[x].r) return ;
int mid = (tree[x].l + tree[x].r) >> 1;
Count(x * 2);
Count(x * 2 + 1);
return ;
}//統計
int main()
{
int n, m, x, y;
scanf("%d", &n);
scanf("%d", &m);
Build(1, 1, n);
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &x, &y);
Ins(1, x, y - 1);
}
Count(1);
printf("%d", ans);
}