poj2777-----线段树------位运算模拟线段染色------求区间颜色种数

来源:互联网 发布:最近网络上很火的歌曲 编辑:程序博客网 时间:2024/05/01 04:41

树状数组建立线段树,每个节点表示颜色值,end表示。。。(我觉得此处end表示延迟, end 为真表示此处有延迟, 为假表示此处没有延迟, 而当前节点的颜色表示当前区间各段的颜色)

此题比较好的是用位运算  或  模拟染色情况。


刚开始考虑用数组表示颜色,写着写着自己都不知道写的什么了。参考的大神的程序。

http://www.cnblogs.com/rainydays/archive/2011/05/14/2046419.html


注意:输入的区间两端点大小的问题。


#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const int maxn=100010;int n, t, op;struct node{    int color;    bool end;}sum[maxn<<2];void build(int l, int r, int rt){    sum[rt].color = 1;    sum[rt].end = true;    if(l == r){        return ;    }    int m = (l+r)>>1;    build(lson);    build(rson);}void Update(int L, int R, int c, int l, int r, int rt){    if(L == l && r == R){        sum[rt].end = true;        sum[rt].color = c;        return ;    }    if(sum[rt].end){        sum[rt].end = false;        sum[rt<<1].color = sum[rt].color;        sum[rt<<1].end = true;        sum[rt<<1|1].color = sum[rt].color;        sum[rt<<1|1].end = true;    }    int m = (l+r)>>1;    if(L <= m){        if(R<=m) Update(L, R, c, lson);        else Update(L, m, c, lson);    }    if(R > m){        if(L<=m) Update(m+1, R, c, rson);        else Update(L, R, c, rson);    }    sum[rt].color = sum[rt<<1].color | sum[rt<<1|1].color;}int Query(int L, int R, int l, int r, int rt){    if(sum[rt].end){        return sum[rt].color;    }    if(l == L && r == R){        return sum[rt].color;    }    int m = (l+r)>>1;    int ret = 0;    if(L <= m){        if(R <= m) Query(L, R, lson);        else Query(L, m, lson);    }    if(R <= m)        return Query(L, R, lson);    else if(L > m)        return Query(L, R, rson);    else return Query(L, m, lson)|Query(m+1, R, rson);}int counter(int a){    int x = 1;    int ret = 0;    for(int i=0; i<32; i++, x<<=1){        if(x & a) ret++;    }    return ret;}int main(){    freopen("in.txt", "r", stdin);    char ch[2];    int a, b, c;    while(scanf("%d %d %d", &n, &t, &op) != EOF){        build(1, n, 1);        while(op--){            scanf("%s", ch);            if(ch[0] == 'C'){                scanf("%d %d %d", &a, &b, &c);                if(a > b) swap(a, b);                Update(a, b, 1<<(c-1), 1, n, 1);            }else if(ch[0] == 'P'){                scanf("%d %d", &a, &b);                if(a > b) swap(a, b);                printf("%d\n", counter(Query(a, b, 1, n, 1)));            }        }    }    return 0;}


原创粉丝点击