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

POJ 2777-题解

时间:2017-10-12 10:32:13      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:return   class   inpu   父节点   ret   源代码   update   math   line   

五、源代码

  

#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-题解

标签:return   class   inpu   父节点   ret   源代码   update   math   line   

原文地址:http://www.cnblogs.com/565261641-fzh/p/7653657.html

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