题目链接:https://vjudge.net/contest/168122#problem/F
给你n次操作,每次操作将【L,R】区间的颜色染色成C,问你最后能看见的颜色有哪些
这题和POJ2528很像,不过POJ2528还需要进行离散化操作,可见线段树确实很灵活。
这题可以作为区间覆盖的模板题,区间覆盖的处理方法都在代码中了,比较简单,但细节需要注意,我就是push_downWA了好几法......
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=8000+5;
int sum[maxn<<2],num[maxn<<2];
int aa;
void pushdown(int rt)
{
if(sum[rt]!=-1)
{
sum[rt<<1]=sum[rt<<1|1]=sum[rt];
sum[rt]=-1;
}
}
void update(int L,int R,int C,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
sum[rt]=C;
return ;
}
int m=(l+r)>>1;
pushdown(rt);
if(L<=m)
update(L,R,C,l,m,rt<<1);
if(R>m)
update(L,R,C,m+1,r,rt<<1|1);
}
void query(int l,int r,int rt)
{
if(l==r)
{
if(sum[rt]!=-1&&sum[rt]!=aa)
{
// printf("**\n");
num[sum[rt]]++;
}
aa=sum[rt];
return ;
}
int m=(r+l)>>1;
pushdown(rt);
query(l,m,rt<<1);
query(m+1,r,rt<<1|1);
}
int main()
{
int n,L,R,C;
while(~scanf("%d",&n))
{
memset(sum,-1,sizeof(sum));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&L,&R,&C);
update(L+1,R,C,1,8000,1);
}
aa=-1;
query(1,8000,1);
for(int i=0;i<=8000;i++)
{
if(num[i])
printf("%d %d\n",i,num[i]);
}
printf("\n");
}
}