[线段树]线段树练习题三

线 段 树 练 习 题 三 线段树练习题三 线


题目描述

给定一条长度为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);
	}
}

posted @ 2020-08-10 09:18  unknown_future  阅读(54)  评论(0编辑  收藏  举报