L i n k Link Link
S S L O J SSLOJ SSLOJ 2644 2644 2644
D e s c r i p t i o n Description Description
桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如右图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少?
I n p u t Input Input
20
4
1 5
3 8
7 10
13 19
O u t p u t Output Output
15
H i n t Hint Hint
数据范围
1<=n<=100000,1<=m<=100000,保证坐标范围为[1,n].
T r a i n Train Train o f of of T h o u g h t Thought Thought
线段树
定义一个参数cover,用于表示当前区间是否被完全覆盖
统计时,计算被覆盖的区间大小就好了
C o d e Code Code
#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);
}