HDOJ-5023-A Corrupt Mayor's Performance Art 解题报告

来源:互联网 发布:拐卖儿童死刑知乎 编辑:程序博客网 时间:2024/05/12 00:36

       一道跟POJ2777线段树基本一样的题,不同点就在于输出时这道题是按照颜色id从小到大输出而不是输出颜色。简单讲一下题意:给围墙染色,P操作代表给坐标为[a,b]的墙染上id为c的颜色,而Q操作表示询问在[a,b]范围内的围墙颜色种类,并且按照升序输出颜色id。


       我的解题思路:肯定和POJ2777线段树一样,使用一个32位整型数来存储颜色(因为有30种颜色,所以不需要开一个长度为30的bool数组,事实上这样是导致TLE的关键)。使用按位或运算计算出范围颜色然后用一个整型数存储。最后写个函数顺序输出id就ok了。


       我的解题代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <ctime>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <queue>#include <stack>#include <list>#include <map>using namespace std;#define N 1000000struct tree     //定义线段树结构体{    int left;    int right;    int mid;    int color;      //这个代表当前范围的颜色    int set;        //延迟标记    void init()    {        mid = (left + right) >> 1;        color = 2;  //初始颜色为2        set = 0;        return;    }};tree node[N<<2];int ans;int n, m;void BuildTree(int left, int right, int x); //建立线段树void P(int left, int right, int co, int x); //P操作int Q(int left, int right, int x);          //Q操作void PushUp(int x);     //向上更新void PushDown(int x);   //向下更新int main(){    char ch;    int a, b, c;    while (~scanf("%d %d", &n, &m))    {        if (n == m && m == 0) break;        BuildTree(1, n, 1);        while (m--)        {            scanf(" %c %d %d", &ch, &a, &b);            if (ch == 'P')            {                scanf("%d", &c);                P(a, b, c, 1);            }            else            {                ans = Q(a, b, 1);                bool flag = false;      //为了使除了最后一个颜色后面输出换行其他都输出一个空格                for (int i=1; i<=30; ++i)                {                    if ((ans & 1) == 1)                    {                        if (flag) putchar(' ');                        printf("%d", i);                        flag = true;                    }                    ans >>= 1;                }                putchar('\n');            }        }    }    return 0;}void BuildTree(int left, int right, int x){    node[x].left = left;    node[x].right = right;    node[x].init();    if (left == right) return;    BuildTree(left, node[x].mid, x << 1);    BuildTree(node[x].mid + 1, right, x << 1 | 1);    return;}void P(int left, int right, int co, int x){    if (node[x].left == left && node[x].right == right)    {        int num = 1;    //颜色id所转换的数        for (int i=1; i<co; ++i) num <<= 1;     //将颜色id转换为颜色数        node[x].set = num;        node[x].color = num;    //这里注意=不要写成|=,就因为这地方错WA了好久...        PushUp(x);        return;    }    if (node[x].set != 0) PushDown(x);    if (right <= node[x].mid)    {        P(left, right, co, x << 1);    }    else if (left > node[x].mid)    {        P(left, right, co, x << 1 | 1);    }    else    {        P(left, node[x].mid, co, x << 1);        P(node[x].mid + 1, right, co, x << 1 | 1);    }    return;}void PushUp(int x){    while (x != 1)    {        x >>= 1;        node[x].color = node[x<<1].color | node[x<<1|1].color;    }    return;}void PushDown(int x){    node[x<<1].color = node[x<<1|1].color = node[x].color;    node[x<<1].set = node[x<<1|1].set = node[x].set;    node[x].set = 0;    return;}int Q(int left, int right, int x){    if (node[x].left == left && node[x].right == right)     {        return node[x].color;    }    if (node[x].set != 0) PushDown(x);    if (right <= node[x].mid)     {        return Q(left, right, x << 1);    }    if (left > node[x].mid)    {        return Q(left, right, x << 1 | 1);    }    return Q(left, node[x].mid, x << 1) | Q(node[x].mid + 1, right, x << 1 | 1);}


0 0