Description
桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如右图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少?
Input
第一行,n
第二行,m
第
3
3
3到
n
+
2
n+2
n+2
每行两个数,为盒子的左右两个坐标
Output
一行,影子的总长
Sample Input
20
4
1 5
3 8
7 10
13 19
Sample Output
15
Hint
1<=n<=100000,1<=m<=100000,保证坐标范围为[1,n].
思路
线段树
详细思路见线段树
修改的见代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
struct tree_1
{
ll l, r, k, store;
}Tree[400250];
int Sum, n, m, k;
void Tree_Buil(int Hi, int l, int r)
{
Tree[Hi].l = l;
Tree[Hi].r = r;
if(l >= r)return;
int Mid = (l + r) >> 1;
Tree_Buil(Hi * 2, l, Mid);
Tree_Buil(Hi * 2 + 1, Mid+1, r);
return;
}
//--------------------------------------------------------------
void Add(int Hi,int l,int r)
{
if(Tree[Hi].k)return;
if(Tree[Hi].l == l && Tree[Hi].r == r)
{
Tree[Hi].k++;
return;
}
if(Tree[Hi].l >= Tree[Hi].r)return;
int Mid = (Tree[Hi].l + Tree[Hi].r) / 2;
if(l <= r && r <= Mid)Add(Hi * 2, l, r);
else if(l > Mid && l <= r)Add(Hi * 2 + 1, l, r);
else
{
Add(Hi * 2, l, Mid);
Add(Hi * 2 + 1, Mid + 1, r);
}
}
//--------------------------------------------------------------
void Num(int Hi)
{
if(Tree[Hi].k == 1)
{
Sum += (Tree[Hi].r-Tree[Hi].l+1);
return;
}
if(Tree[Hi].l>=Tree[Hi].r)return;
Num(Hi * 2);
Num(Hi * 2 + 1);
return;
}
//--------------------------------------------------------------
int main()
{
Sum=0;
scanf("%d%d",&n,&m);
Tree_Buil(1,1,n);
for(int i=1;i<=m;++i)
{
int l,r;
scanf("%d%d",&l,&r);
Add(1,l,r - 1);
}
Num(1);
printf("%d",Sum);
return 0;
}