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

POJ 2777 Count Color

时间:2015-07-27 21:00:57      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:区间更新   状压   

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

题意:给定长度L的区间,初始全部为1。

两种操作
1. 更新:C A B C 将区间[A,B]全部赋值为C。
2. 查询:P A B 查询区间[A,B]的颜色种数。

思路:基本为裸的区间更新。
因为最多只有30种颜色,所以在存储某个区间的颜色类型和种数时,可以利用一个int数来存储(利用每一位的二进制,1为有该颜色,0位无该颜色)。

代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

const int N = 1e5 + 5;
const int INF = 1e9 + 10;
const double EPS = 1e-6;

int board[N << 2];
int lazy[N << 2];

void pushup(int rt) {
    board[rt] = board[rt << 1] | board[rt << 1 | 1];
}

void pushdown(int rt) {
    if (lazy[rt] != -1) {
        lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
        board[rt << 1] = lazy[rt];
        board[rt << 1 | 1] =  lazy[rt];
        lazy[rt] = -1;
    }
}

void build(int l, int r, int rt) {
    lazy[rt] = -1;
    if (l == r) {
        board[rt] = 1;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void update(int c, int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) {
        board[rt] = c;
        lazy[rt] = c;
        return ;
    }
    pushdown(rt);
    int m = (l + r) >> 1;
    if (L <= m)
        update(c, L, R, lson);
    if (R > m)
        update(c, L, R, rson);
    pushup(rt);
}

int query(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) {
        return board[rt];
    }
    pushdown(rt);
    int m = (l + r) >> 1;
    int ql = 0, qr = 0, res;
    if (L <= m)
        ql = query(L, R, lson);
    if (R > m)
        qr = query(L, R, rson);
    res = ql | qr;
    pushup(rt);
    return res;
}

int main() {

    int L, T, O;
    while (scanf("%d%d%d", &L, &T, &O) != EOF) {
        build(1, L, 1);
        for (int i_q = 1; i_q <= O; i_q++) {
            char str[2];
            int l, r;
            scanf("%s%d%d", str, &l, &r);
            if (l > r)
                swap(l, r);
            if (str[0] == ‘C‘) {
                int c;
                scanf("%d", &c);
                c = (1 << (c - 1));
                update(c, l, r, 1, L, 1);
            }
            else {
                int res = query(l, r, 1, L, 1);
                int co = 0;
                while (res) {
                    if (res & 1)
                        co++;
                    res >>= 1;
                }
                printf("%d\n", co);
            }
        }
        cout << endl;
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2777 Count Color

标签:区间更新   状压   

原文地址:http://blog.csdn.net/u014357885/article/details/47090327

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