与上一题一样,
仍然定义tree如下:
tree=-1表示该区间由多种颜色组成。
tree>=0表示该区间只有一种单一的颜色cover。
插入操作与线段树 3 3 3一样
值得注意的是统计操作
long long ccount(long long x,long long l,long long r,long long &lc,long long &rc)
{
long long lt=0,rt=0;
if(tree[x]!=-1) //如果当前节点只有一种颜色
{
lc=rc=tree[x]; //传递
return 1; //就当成一段
}
if(l==r) //如果是叶子结点,就是一种颜色
return 1;
long long mid=(l+r)/2;
long long sum=ccount(x*2,l,mid,lc,lt)+ccount(x*2+1,mid+1,r,rt,rc);
//把当前节点的左右子节点的颜色段全部加上
if(rt==lt) //如果当前节点的左右子节点颜色重复
return sum-1; //就剪去一个多算的
else
return sum;
}
#include
#include
#include
#include
using namespace std;
long long n,m,l[4000010],r[4000010],w[4000010];
long long tree[400010];
void insert(long long a,long long b,long long l,long long r,long long x,long long color)
{
if(a>b)
return;
if(tree[x]==color)
return;
if(a==l&&b==r)
tree[x]=color;
else
{
long long mid=(l+r)/2;
if(tree[x]!=-1)
{
tree[2*x]=tree[2*x+1]=tree[x];
tree[x]=-1;
}
if(b<=mid)
insert(a,b,l,mid,x*2,color);
else if(a>mid)
insert(a,b,mid+1,r,x*2+1,color);
else
{
insert(a,mid,l,mid,x*2,color);
insert(mid+1,b,mid+1,r,x*2+1,color);
}
}
}
long long ccount(long long x,long long l,long long r,long long &lc,long long &rc)
{
long long lt=0,rt=0;
if(tree[x]!=-1) //如果当前节点只有一种颜色
{
lc=rc=tree[x]; //传递
return 1; //就当成一段
}
if(l==r) //如果是叶子结点,就是一种颜色
return 1;
long long mid=(l+r)/2;
long long sum=ccount(x*2,l,mid,lc,lt)+ccount(x*2+1,mid+1,r,rt,rc);
//把当前节点的左右子节点的颜色段全部加上
if(rt==lt) //如果当前节点的左右子节点颜色重复
return sum-1; //就剪去一个多算的
else
return sum;
}
int main()
{
cin>>n>>m;
for(long long i=1; i<=n; i++)
{
scanf("%lld%lld%lld",&l[i],&r[i],&w[i]);
insert(l[i],r[i],1,m,1,w[i]);
}
long long l=0,ling=0; //因为是指针,所以要定义两个变量
cout<<ccount(1,1,m,l,ling);
return 0;
}