POJ2777线段树....

来源:互联网 发布:数据库压力测试工具 编辑:程序博客网 时间:2024/05/21 09:00

应该是这次刷题最后一次线段树了…区间更新+binary。
区间更新在pushdown时将子节点的color和flag都置为父节点的flag.重要的是二值化。即将一个数表示成位运算。此时pushup使用或操作即可。

////  main.cpp//  POJ2777////  Created by dan on 16/10/9.//  Copyright © 2016年 dan. All rights reserved.//#include <iostream>#include <set>#define MAXN 100005using namespace std;struct Node{    int flag;    int color;};Node sum[MAXN << 2];void pushUp(int i){    sum[i].color = sum[i << 1].color | sum[i << 1 | 1].color;}void build(int i, int l, int r){    sum[i].color = sum[i].flag = 0;    if (l == r){        sum[i].color = 1;        return;    }    int m = (r + l) >> 1;    build(i << 1, l, m);    build(i << 1 | 1, m + 1, r);    pushUp(i);}void pushDown(int i){    if (sum[i].flag){        sum[i << 1].flag = sum[i << 1 | 1].flag = sum[i].flag;        sum[i << 1].color = sum[i << 1 | 1].color = sum[i].flag;        sum[i].flag = 0;    }}void update(int begin, int end ,int colorNum, int l, int r, int savPos){    if (begin <= l && r <= end){        sum[savPos].color = (1 << (colorNum-1));        sum[savPos].flag = (1 << (colorNum-1));        return;    }   if (l > end  || r < begin)        return;    pushDown(savPos);    int m = (r + l) / 2;    if (begin <= m)        update(begin, end, colorNum, l, m, savPos << 1);    if (m < end)        update(begin, end, colorNum, m + 1, r, (savPos << 1 | 1));    pushUp(savPos);    return;}int query(int begin, int end, int l, int r, int savPos){    if ( begin <= l && r <= end)        return sum[savPos].color;    if (l > end  || r < begin)        return 0;    pushDown(savPos);    int m = (r + l) / 2;    return (query(begin, end, l, m, savPos << 1) | query(begin, end, m + 1, r, (savPos << 1 | 1)));}int ans(int x){    int aa = 0 ;    while(x)    {        if(x & 1)            aa++ ;        x >>= 1 ;    }    return aa ;}int main(int argc, const char * argv[]) {    int L, T, O;    scanf("%d%d%d", &L, &T, &O);    int l, r, x;    build(1, 1, L);    char str[10];    while(O--){        scanf("%s", str);        if(str[0] == 'C')        {            scanf("%d %d %d", &l, &r, &x);            if(l > r)                swap(l,r);            update(l, r, x, 1, L,1);        }        else        {            scanf("%d %d", &l, &r);            if(l > r)                swap(l,r);            printf("%d\n",ans( query(l, r, 1, L, 1) ) );        }    }}
0 0