POJ 2777-题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2777-题解相关的知识,希望对你有一定的参考价值。

五、源代码

  

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
using namespace std;
typedef long long LL;
const int MAXN = 100010;
int data[MAXN << 2];
int n, m, q;

void init(int root = 1, int l = 1, int r = n) {
    data[root] = 2;//注意啊,初始颜色是1。位值就是1<<1=2。坑啊,在这里调了几个小时。
    if(l < r) {
        int mid = (l + r) >> 1;
        init(root << 1, l, mid);
        init(root << 1 | 1, mid + 1, r);
    }
}

void pushDown(int root) {
    if(data[root] != 1 && (data[root] & (data[root] - 1)) == 0){
        data[root << 1] = data[root];
        data[root << 1 | 1] = data[root];
        //data[root] = 2;
        /*注意啊,颜色位值下推后,父节点的值不要变啊,否则查询就变成O(N)了。*/
    }
}

void update(int ul, int ur, int ct, int root = 1, int l = 1, int r = n) {
    if(l > ur || r < ul)return;
    if(l >= ul && r <= ur)data[root] = 1 << ct;
    else {
        pushDown(root);
        int mid = (l + r) >> 1;
        if(ul <= mid)update(ul, ur, ct, root << 1, l, mid);
        if(ur > mid)update(ul, ur, ct, root << 1 | 1, mid + 1, r);
        data[root] = data[root << 1] | data[root << 1 | 1];//注意更新父节点的位值。
    }
}

int query(int ul, int ur, int root = 1, int l = 1, int r = n) {
    if(l > ur || r < ul)return 0;
    if(l >= ul && r <= ur)return data[root];
    else {
        pushDown(root);
        int mid = (l + r) >> 1;
        int lch = 0, rch = 0;
        if(ul <= mid)lch = query(ul, ur, root << 1, l, mid);
        if(ur > mid)rch = query(ul, ur, root << 1 | 1, mid + 1, r);
        return lch | rch;
    }
}

int main() {
#ifndef ONLINE_JUDGE
    //freopen("Cinput.txt", "r", stdin);
   //freopen("Coutput2.txt", "w", stdout);
#endif // ONLINE_JUDGE
    char op;
    int A, B, C;
    while(~scanf("%d%d%d", &n, &m, &q)) {
        init();
        for(getchar(); q--; getchar()) {
            scanf("%c", &op);
            switch(op) {
            case C: {
                scanf("%d%d%d", &A, &B, &C);
                if(A > B)swap(A, B);
                update(A, B, C);
                break;
            }
            case P: {
                scanf("%d%d", &A, &B);
                if(A > B)swap(A, B);
                int res = query(A, B);
                printf("%d\n", __builtin_popcount(res));
                break;
            }
            }
        }
    }
    return 0;
}

 

以上是关于POJ 2777-题解的主要内容,如果未能解决你的问题,请参考以下文章

POJ2777解题报告

poj 2777

POJ 2777Count Color

POJ2777-Count Color 线段树

POJ2777

poj2777 Count Color