题面:
在数轴上进行一系列操作。每次操作有两种类型,一种是在线段[a,b]上涂上颜色,另一种将[a,b]上的颜色擦去。
问经过一系列的操作后,有多少条单位线段[k,k+1]被涂上了颜色
Input:
第一行两个整数n,m,表示数轴从0到n,操作数为m
接下来m行,每行三个整数op,a,b,op=0时表示将[a,b]上的颜色擦去,op=1时表示在线段[a,b]上涂上颜色
n,m<=100000
Output:
输出一个整数,表示有多少条单位线段[k,k+1]被涂上了颜色
Solution:
线段树,tree数组记录当前区间被染色的长度,如果当前区间全部被染色,则令tree值等于当前区间长度,值得一提的是,要记录区间长度,只需要记录l+1到r的点数就行了
Code:
#include<bits/stdc++.h>
#define N 400001
using namespace std;
int n,m;
struct sgt{
#define ls (q<<1)
#define rs (q<<1|1)
int tree[N],lazy[N];
void add(int l,int r,int q,int v){
tree[q]=r-l+1;
if(v==-1)tree[q]=0;
lazy[q]=v;
}
void pushdown(int l,int r,int q){
if(lazy[q]==0)return ;
int mid=(l+r)>>1;
add(l,mid,ls,lazy[q]);
add(mid+1,r,rs,lazy[q]);
lazy[q]=0;
}
void change(int l,int r,int L,int R,int q,int v){
if(l>R||r<L)return ;
if(l>=L&&r<=R)return add(l,r,q,v);
pushdown(l,r,q);
int mid=(l+r)>>1;
if(mid>=L)change(l,mid,L,R,ls,v);
if(mid<R)change(mid+1,r,L,R,rs,v);
tree[q]=tree[ls]+tree[rs];
}
int ans(){
pushdown(1,n,1);
return tree[1];
}
}T;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main(){
n=read();m=read();
for(int i=1;i<=m;i++){
int opt,x,y;
opt=read();x=read();y=read();
if(opt==0)opt--;
x++;
T.change(1,n,x,y,1,opt);
}
printf("%d",T.ans());
return 0;
}