//ZOJ 1610 Count the Colors 线段树 成段更新 单点求值
/*
题意:
有一个0-8000的区间,每次将一个子区间染色,颜色用整数表示,
如果一段区间被重复染色的话,它的颜色会被后面染上去的颜色覆盖
问最后有几种颜色出现,每种颜色的区间有多少个
思路:
注意是对区间染色,不是对点染色。
成段更新 单点求值
由于不需要知道父节点的信息,所以不需要pushup。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define N 8005
int add[N<<2],color[N];
int n;
void Pushdown(int rt){
if(add[rt] != -1){
add[rt<<1] = add[rt<<1|1] = add[rt];
add[rt] = -1;
}
}
void Build(){
memset(add,-1,sizeof(add));
memset(color,0,sizeof(color));
}
void Update(int rt,int l,int r,int L,int R,int val){
if(L <= l && R >= r){
add[rt] = val;
return ;
}
Pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) Update(lson,L,R,val);
if(R > mid ) Update(rson,L,R,val);
}
int Query(int rt,int l,int r,int x){
if(l == r){
return add[rt];
}
Pushdown(rt);
int mid = (l + r) >> 1;
if(x <= mid) Query(lson,x);
else Query(rson,x);
}
int main(){
int i;
int a,b,c;
int mmax,mmin;
int pre;
while(scanf("%d",&n)!=EOF){
Build();
mmax = -1;
mmin = 8001;
for(i = 1; i <= n; ++i){
scanf("%d %d %d",&a,&b,&c);
if(b > mmax) mmax = b;
if(a+1 < mmin) mmin = a+1;
Update(1,1,8000,a+1,b,c);
}
pre = Query(1,1,8000,mmin);
++color[pre];
for(i = mmin+1; i <= mmax; ++i){
int tmp = Query(1,1,8000,i);
if(tmp != pre){
pre = tmp;
++color[pre];
}
}
for(i = 0; i <= 8000; ++i)
if(color[i])
printf("%d %d\n",i,color[i]);
puts("");
}
return 0;
}
ZOJ 1610 Count the Colors 线段树 成段更新 单点求值
最新推荐文章于 2020-11-25 09:25:13 发布