poj 2777 Count Color

来源:互联网 发布:旧版手机淘宝2014安卓 编辑:程序博客网 时间:2024/06/06 09:33

题目链接:http://poj.org/problem?id=2777

题意:有一根长为L的木板,有两种对木板的操作,一种是把一段木板[a, b]涂成一种颜色,另一种操作是求木板段[a, b]中共有多少种颜色。其中颜色有T种, 木板默认的颜色是颜色1.

方法:线段树,这个道题的技巧是要用到位操作,因为颜色最多有30种。其中要用到Lazy-Tag的思想。

代码如下:

#include <iostream>#include <cstdio>#define MAX 100001using namespace std;struct node{      int l, r, color;      bool flag;}v[5*MAX];void pushup(int n){      v[n].color = v[2*n].color | v[2*n+1].color;}void pushdown(int n){      if (v[n].flag)      {            v[2*n].flag = true;            v[2*n+1].flag = true;            v[2*n].color = v[n].color;            v[2*n+1].color = v[n].color;            v[n].flag = false;      }}void build(int l, int r, int n){      v[n].l = l;      v[n].r = r;      v[n].flag = false;      if (l == r)      {            v[n].color = 1;            return ;      }      int mid = (l+r)/2;      build(l, mid, 2*n);      build(mid+1, r, 2*n+1);      pushup(n);}void update(int l, int r, int d, int n){      if (l<=v[n].l && v[n].r<=r)      {            v[n].flag = true;            v[n].color = 1<<(d-1);            return ;      }      pushdown(n);      int mid = ( v[n].l + v[n].r )/2;      if (r<=mid)            update(l, r, d, 2*n);      else if (l > mid)            update(l, r, d, 2*n+1);      else      {            update(l, mid, d, 2*n);            update(mid+1, r, d, 2*n+1);      }      pushup(n);}int query(int l, int r, int n){      if (l<=v[n].l && v[n].r<=r)            return v[n].color;      pushdown(n);      int mid = (v[n].l + v[n].r)/2;      if (r <= mid)            return query(l, r, 2*n);      else if (l > mid)            return query(l, r, 2*n+1);      else            return query(l, mid, 2*n) | query(mid+1, r, 2*n+1);}int main(){      int L, T, O, a, b, c;      char ch;      while (~scanf("%d%d%d", &L, &T, &O))      {            build(1, L, 1);            while (O--)            {                  getchar();                  scanf("%c", &ch);                  if (ch == 'C')                  {                        scanf("%d %d %d", &a, &b, &c);                        if (a<b)                              update(a, b, c, 1);                        else                              update(b, a, c, 1);                  }                  else                  {                        scanf("%d %d", &a, &b);                        int t;                        if (a < b)                              t = query(a, b, 1);                         else                              t = query(b, a, 1);                        int len = 0;                        for(int i=0; i<T; i++)                              if(t & (1<<i))                                    len++;                        printf("%d\n", len);                  }            }      }      return 0;}


原创粉丝点击