题意:
8001个点【0,8000】,颜色【0,8000】
修改:将点【l,r】之间的段染色为c
最后一次查询:对每种颜色i 输出 出现连续颜色i的段数(没有颜色i的段就不用输出)
跟poj2528异曲同工
思路:
不要维护点。。维护段。。【0,1】看成第一段【1,2】看成第二段,以此类推
修改:区间维护col:区间颜色(区间内多于一种颜色,col为-1)
查询: 暴力查询到叶子,tem【i】表示第i段是什么颜色
(不要怕TLE,只有一次查询)
(由于左子树先遍历,第i段肯定是第i个遍历到的)
然后统计一下就好了,注意中间没有染色的要分成两段
难度:0.8
30ms
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct stree{
int col;
}sts[8005*4];
int tem[8005];
int num[8005];
int tot=0;
void pushup(int root)//最后发现其实不需要这个,因为最后查询都会暴力到根节点了 但有这个会快一点
{
if((sts[root<<1].col==sts[root<<1|1].col))
sts[root].col=sts[root<<1].col;
}
void pushdown(int root)
{
if(sts[root].col!=-1)//避难
{
sts[root<<1].col=sts[root].col;
sts[root<<1|1].col=sts[root].col;
sts[root].col=-1;
}
}
void build(int l,int r,int root)//-1走起
{
sts[root].col=-1;
if(l==r)//leaf
return ;
else
{
int mid=(l+r)>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushup(root);
}
}
void update(int nowl,int nowr,int ul,int ur,int root,int addval)
{
if(ul<=nowl&&ur>=nowr)
{
sts[root].col=addval;
return ;
}
else
{
int mid=(nowl+nowr)>>1;
pushdown(root);
if(ul<=mid) update(nowl,mid,ul,ur,root<<1,addval);//这里顺手写成ur
if(ur>mid) update(mid+1,nowr,ul,ur,root<<1|1,addval);
pushup(root);
}
}
void query(int nowl,int nowr,int root)//暴力过一遍好了= =
{
if(nowl==nowr) //易错点: 以为-1就不用算进去,其实1 2 1, 4 5 1 算两段
{
tem[tot++]=sts[root].col;//DFS序..遍历到叶子先后是按顺序的
return ;
}
else
{
pushdown(root);
int mid=(nowl+nowr)>>1;
query(nowl,mid,root<<1);
query(mid+1,nowr,root<<1|1);
}
}
void op();
int main()
{
int n;int l,r,c;
while(~scanf("%d",&n))
{
build(1,8000,1);
// op();
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&l,&r,&c);
update(1,8000,l+1,r,1,c);
//op();
}
tot=0;
memset(tem,-1,sizeof(tem));
query(1,8000,1);
memset(num,0,sizeof(num));
// printf("%d",tot);
// for(int i=0;i<tot;)
// {
// printf("%d",tem[i]);
// }
// printf("\n");
int i;int j;
for(i=0;i<tot;)
{
if(tem[i]==-1)
{
i++;
continue;
}
num[tem[i]]++;
for(j=i+1;j<tot;j++)
{
if((tem[j]!=tem[i])||(tem[j]==-1))
break;
}
i=j;
}
for(int i=0;i<=8000;i++)
{
if(num[i])
printf("%d %d\n",i,num[i]);
}
printf("\n");
}
}
void sp(int t)
{
for(int i=1;i<=t;i++)
printf(" ");
}
void op()
{
int pow2[10]={1,2,4,8,16,32};int n=16;
printf("\n///\n");
for(int i=1; i<=31; i++)
{
if(i==pow2[0])sp(15);
if(i==pow2[1])sp(7);
if(i==pow2[2])sp(3);
if(i==pow2[3])sp(1);
if(i>pow2[1]&&i<pow2[2])sp(15);
if(i>pow2[2]&&i<pow2[3])sp(7);
if(i>pow2[3]&&i<pow2[4])sp(3);
if(i>pow2[4]&&i<pow2[5])sp(1);
printf("%d",sts[i].col);
if((i==pow2[1]-1)||(i==pow2[2]-1)||(i==pow2[3]-1)||(i==pow2[4]-1))
printf("\n");
}
printf("\n///\n\n");
}