[线段树]线段树练习题三
线 段 树 练 习 题 三 线段树练习题三 线段树练习题三
题目描述
给定一条长度为m的线段,有n个操作,每个操作有3个数字x,y,z表示把区间[x,y]染成颜色z,询问染完色之后,这条长度为m的线段一共有几种颜色。规定:线段的颜色可以相同。连续的相同颜色被视作一段。问x轴被分成多少段。
样例输入
4 20 //四条,总长度为20
10 19 1
2 9 2
5 13 3
15 17 4
样例输出
7
数据范围
N <= 10000
M <= 1000000
code
#include<stdio.h>
#include<iostream>
using namespace std;
int n,m,l,r,z,tr[400001]={0},ans=-1;
int countt(int t,int a,int b);
void insertt(int t,int a,int b,int x,int y,int c);
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&l,&r,&z);
insertt(1,1,m,l,r,z);
}
printf("%d",countt(1,1,m));
return 0;
}
int countt(int t,int a,int b){
int mid=(a+b)/2;
if(tr[t]>=0){
int s=1;
if(tr[t]==ans)
s=0;
ans=tr[t];
return s;
}
return countt(t*2,a,mid)+countt(t*2+1,mid,b);
}
void insertt(int t,int x,int y,int a,int b,int c){
if(x==a and y==b){
tr[t]=c;
return ;
}
if(tr[t]>=0){
tr[t*2]=tr[t*2+1]=tr[t];
tr[t]=-1;
}
int mid=(x+y)/2;
if(b<=mid){
insertt(t*2,x,mid,a,b,c);
}
else if(a>=mid){
insertt(t*2+1,mid,y,a,b,c);
}
else{
insertt(t*2,x,mid,a,mid,c);
insertt(t*2+1,mid,y,mid,b,c);
}
}