现在的位置: 首页 > 算法 > 正文

poj – 2777 – Count Color(线段树)

2019年08月29日 算法 ⁄ 共 1337字 ⁄ 字号 评论关闭

题意:长为L的区间,初始每个单位区间都为颜色1,执行两种操作,C A B C,将区间[A, B]染为颜色C,P A B,询问区间A, B]有多少种颜色(1 <= L <= 100000, 1 <= 颜色T <= 30)。

题目链接:http://poj.org/problem?id=2777

——>>不错的题目,因为颜色的各类只有30种,所以每种颜色可以用1移位来表示,设col[o]表示线段树结点o的颜色状态,那么col[o]的低30位有多少个1就表示有多少种颜色。。。#^_^

#include <cstdio>
#include <algorithm>

using namespace std;

#define lc (o<<1)
#define rc ((o<<1)+1)

const int maxn = (100000 + 10) << 2;

bool one[maxn];     //是否为单一色
int col[maxn], sum;

void build(int o, int l, int r) {
    col[o] = 1;     //初始为颜色1
    one[o] = true;      //是单一色
    if(l == r) return;
    int m = (l + r) >> 1;
    build(lc, l, m);
    build(rc, m+1, r);
}

void pushdown(int o) {
    col[lc] = col[rc] = col[o];
    one[lc] = one[rc] = true;
    one[o] = false;
}

void update(int o, int l, int r, int ql, int qr, int v) {
    if(ql <= l && r <= qr) {
        col[o] = v;
        one[o] = true;
        return;
    }
    if(col[o] == v) return;
    if(one[o]) pushdown(o);
    int m = (l + r) >> 1;
    if(ql <= m) update(lc, l, m, ql, qr, v);
    if(qr > m) update(rc, m+1, r, ql, qr, v);
    col[o] = col[lc] | col[rc];
}

void query(int o, int l, int r, int ql, int qr) {
    if((ql <= l && r <= qr) || one[o]) {
        sum |= col[o];
        return;
    }
    int m = (l + r) >> 1;
    if(ql <= m) query(lc, l, m, ql, qr);
    if(qr > m) query(rc, m+1, r, ql, qr);
}

int solve() {
    int ret = 0;
    for(int i = 0; i < 30; i++)
        if((1<<i) & sum)
            ret++;
    return ret;
}

int main()
{
    int L, T, O, A, B, C;
    char op;
    while(scanf("%d%d%d", &L, &T, &O) == 3) {
        build(1, 1, L);
        while(O--) {
            getchar();
            op = getchar();
            if(op == 'C') {
                scanf("%d%d%d", &A, &B, &C);
                if(A > B) swap(A, B);
                update(1, 1, L, A, B, 1<<(C-1));
            }
            else {
                sum = 0;
                scanf("%d%d", &A, &B);
                if(A > B) swap(A, B);
                query(1, 1, L, A, B);
                printf("%d\n", solve());
            }
        }
    }
    return 0;
}

抱歉!评论已关闭.