题目描述
在数轴上进行一系列操作。每次操作有两种类型,一种是在线段[a,b]上涂上颜色,另一种将[a,b]上的颜色擦去。问经过一系列的操作后,有多少条单位线段[k,k+1]被涂上了颜色。
输入格式
第1行:2个整数n(0<=n<=60000)和m(1<=m<=60000)分别表示数轴长度和进行操作的次数。 接下来m行,每行3个整数i,a,b, 0 <=a<=b<=60000,若i=1表示给线段[a,b]上涂上颜色,若i=2表示将[a,b]上的颜色擦去。
输出格式
文件输出仅有一行为1个整数,表示有多少条单位线段[k,k+1]被涂上了颜色。
样例数据
样例输入
10 5 1 2 8 2 3 6 1 1 10 2 4 7 1 1 5
样例输出
7
题目分析
最为经典的一道区间修改区间查询加懒标记的题了 懒标记的实质:推迟信息更新,避免无用操作 如果不加懒标记,线段树连暴力都不如。 对于每个非完全包含的区间,在修改和查询到的时候都要向下传标记。 比如此题,如果标记为全部有色,传下去儿子结点全部有色,全部无色亦然。传完标记后需要将标记置为0表示儿子中有的有颜色有的无颜色。 因为建树方式不同,线段映射到点右端点需-1
源代码
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const
int Get_Int() {
int num=
0,bj=
1;
char x=getchar();
while(x<
'0'||x>
'9') {
if(x==
'-')bj=-
1;
x=getchar();
}
while(x>=
'0'&&x<=
'9') {
num=num*
10+x-
'0';
x=getchar();
}
return num*bj;
}
const
int maxn=
60000;
struct Tree {
int left,right,lazy,colored;
};
struct Segment_Tree {
Tree tree[maxn*
4];
int sum;
void build(
int index,
int Left,
int Right) {
tree[
index].left=Left;
tree[
index].right=Right;
tree[
index].lazy=
0;
tree[
index].colored=
0;
if(Left==Right)
return;
int mid=(Left+Right)/
2;
build(
2*
index,Left,mid);
build(
2*
index+
1,mid+
1,Right);
}
void push_down(
int index) {
if(tree[
index].lazy==-
1) {
tree[
index*
2].lazy=tree[
index*
2+
1].lazy=-
1;
tree[
index*
2].colored=tree[
index*
2+
1].colored=
0;
tree[
index].lazy=
0;
}
else if(tree[
index].lazy==
1) {
tree[
index*
2].lazy=tree[
index*
2+
1].lazy=
1;
tree[
index*
2].colored=tree[
index*
2].right-tree[
index*
2].left+
1;
tree[
index*
2+
1].colored=tree[
index*
2+
1].right-tree[
index*
2+
1].left+
1;
tree[
index].lazy=
0;
}
}
void push_up(
int index) {
tree[
index].colored=tree[
index*
2].colored+tree[
index*
2+
1].colored;
}
void modify(
int index,
int Left,
int Right,
int data) {
if(Right<tree[
index].left||Left>tree[
index].right)
return;
if(tree[
index].lazy==data)
return;
if(Left<=tree[
index].left&&Right>=tree[
index].right) {
tree[
index].lazy=data;
if(data==
1)tree[
index].colored=tree[
index].right-tree[
index].left+
1;
else tree[
index].colored=
0;
return;
}
push_down(
index);
modify(
index*
2,Left,Right,data);
modify(
index*
2+
1,Left,Right,data);
push_up(
index);
}
};
Segment_Tree st;
int n,m;
int main() {
n=Get_Int();
m=Get_Int();
st.build(
1,
1,n);
for(
int i=
1; i<=m; i++) {
int order=Get_Int(),Left=Get_Int(),Right=Get_Int()-
1;
if(
order==
1)st.modify(
1,Left,Right,
1);
else st.modify(
1,Left,Right,-
1);
}
printf(
"%d\n",st.tree[
1].colored);
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-662519.html