码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-08-22 16:04:18      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ace   struct   paint   std   题意   microsoft   数组   view   define   

题意 : 给出 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 (线段树成段更新)

标签:ace   struct   paint   std   题意   microsoft   数组   view   define   

原文地址:http://www.cnblogs.com/Rubbishes/p/7411546.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!