ZOJ 1610 Count the Colors (线段树成段更新)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ 1610 Count the Colors (线段树成段更新)相关的知识,希望对你有一定的参考价值。

题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个

 

分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以对于区间(L, R)我们只要让左端点+1即可按照正常的线段树操作来做。

 

技术分享
#include<bits/stdc++.h>
#define lson l,   m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 8000 + 5;
const int INF = 0x3f3f3f3f;
struct Query{ int L, R, val; };
int col[maxn<<2], cnt[maxn], Rmax, ColorMax;
Query Q[maxn];

inline void PutDown(int rt)
{
    if(col[rt] >= 0){
        col[rt<<1] = col[rt<<1|1] = col[rt];
        col[rt] = -1;
    }
}

inline void update(int L, int R, int val, int l, int r, int rt)
{
    if(L <= l && r <= R){
        col[rt] = val;
        return ;
    }
    PutDown(rt);
    int m = (l + r) / 2;
    if(L <= m) update(L, R, val, lson);
    if(R >  m) update(L, R, val, rson);
}

int query(int pos, int l, int r, int rt)
{
    if(l == r) return col[rt];
    PutDown(rt);
    int m = (l + r) / 2;
    int ret;
    if(pos <= m) ret = query(pos, lson);
    if(pos >  m) ret = query(pos, rson);
    return ret;
}

int main(void)
{
    int paint;
    while(~scanf("%d", &paint)){

        Rmax = ColorMax = -INF;

        for(int i=1; i<=paint; i++){
            scanf("%d %d %d", &Q[i].L, &Q[i].R, &Q[i].val);
            Q[i].L++;
            Rmax = max(Rmax, Q[i].R);///记录区间右端可以多大
            ColorMax = max(ColorMax, Q[i].val);///记录颜色的最大值
        }
        
        memset(col, -1, sizeof(col));
        for(int i=1; i<=paint; i++){
            if(Q[i].L-1 < Q[i].R)///说明给出的是一个点,没有覆盖掉哪一段,不用更新
                update(Q[i].L, Q[i].R, Q[i].val, 1, Rmax, 1);
        }

        memset(cnt, 0, sizeof(cnt));
        int last = -1;
        for(int i=1; i<=Rmax; i++){///查询区间内每个点的信息,用cnt[]数组来记录拥有的这些颜色占的段数
            int color = query(i, 1, Rmax, 1);
            if(color == -1) {last = -1; continue;}///注意如果没有被染色,last要赋值成-1,不能直接continue
            if(color != last){
                cnt[color]++;
            }
            last = color;
        }

        for(int i=0; i<=ColorMax; i++){
            if(cnt[i]>0){
                printf("%d %d\n", i, cnt[i]);
            }
        }
        puts("");
    }
    return 0;
}
View Code

 

瞎 : query操作的时候由于有lazy tag所以需要PutDown,此题虽然不难但是如果独立写一个线段树并且AC估计能够发现自身的一些问题,注意实现细节....

以上是关于ZOJ 1610 Count the Colors (线段树成段更新)的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ - 1610 Count the Colors 线段树区间修改

zoj 1610 Count the Colors 区间覆盖 求染色段

Count the Colors ZOJ - 1610

kuangbin专题七 ZOJ1610 Count the Colors (灵活线段树)

ZOJ1610 Count the Colors 线段树

ZOJ - 1610 Count the Colors(线段树区间更新)