POJ 2777 Count Color(线段树 + 状态压缩)

来源:互联网 发布:javascript打印菱形 编辑:程序博客网 时间:2024/06/06 11:04

题目大意:
长度为L的一块板, 被分为L个长度为1的小板,编号为1 ~ L。有两种操作,操作C后面跟三个数A,B,C,代表第A块板到第B块板涂上颜色C,操作B后面A,B,需要你输出第A块板到第B块板上共有多少种不同的颜色。颜色的种类最多30种,L和操作数最大都是10万。
解题思路:
很明显的线段树。问题的关键是怎么保存、更新、询问树上每个节点上有哪些颜色。看到颜色的种类不会大于30种这个条件,我相信很多人都会窃喜,这不就是状态压缩么?更新的时候用一个“位或”操作就行了。
大概的思路也真的是这样。这道题目我是敲了很久,可能线段树真的是我的薄弱点吧。不过每一段代码我都是用心去写的,希望勿喷!

Show me the code!

#include <iostream>#include <cstdio>#define mid l + (r - l) / 2#define lson id << 1, l, mid#define rson id << 1 | 1, mid + 1, rusing namespace std;const int MAXN = 1e5;int tree[MAXN * 4], laze[MAXN * 4], ans;void build(int id, int l, int r) {    laze[id] = 0;    if (l == r) {        tree[id] = 1;    }    else {        build(lson);        build(rson);        tree[id] = tree[id << 1] | tree[id << 1 | 1];    }}void pushdown(int id) {    tree[id << 1] = laze[id];    laze[id << 1] = laze[id];    tree[id << 1 | 1] = laze[id];    laze[id << 1 | 1] = laze[id];    laze[id] = 0;}void updata(int id, int l, int r, int L, int R, int val) {    if (R < l || L > r) return;    if (L <= l && r <= R) {        tree[id] = val;        laze[id] = val;        return;    }    if (laze[id]) pushdown(id);    updata(lson, L, R, val);    updata(rson, L, R, val);    tree[id] = tree[id << 1] | tree[id << 1 | 1];}void query(int id, int l, int r, int L, int R) {    if (R < l || L > r) return;    if (L <= l && r <= R) {        ans |= tree[id];        return;    }    if (laze[id]) pushdown(id);    query(lson, L, R);    query(rson, L, R);    tree[id] = tree[id << 1] | tree[id << 1 | 1];}int count(unsigned int N) {    int res = 0;    while (N) {        res += N & 1;        N >>= 1;    }    return res;}int main() {    int L, T, O;    scanf("%d%d%d", &L, &T, &O);    build(1, 1, L);    for (int a = 0; a < O; ++a) {        char op;        getchar();        scanf("%c", &op);        if (op == 'C') {            int b, c, d;            scanf("%d%d%d", &b, &c, &d);            if (b > c) swap(b, c);            updata(1, 1, L, b, c, 1 << (d - 1));        }        else {            int b, c;            scanf("%d%d", &b, &c);            if (b > c) swap(b, c);            ans = 0;            query(1, 1, L, b, c);            printf("%d\n", count(ans));        }    }    return 0;}
0 0
原创粉丝点击