Count Color (线段树区间染色?二进制状态压缩)

Posted -ackerman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Count Color (线段树区间染色?二进制状态压缩)相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/problem/POJ-2777

 

题意:

有L个画板,30种颜色,o个操作:P a b :询问a-b 种有多少种颜色不同的,C  a b c:把a-b全部涂成c的颜色(覆盖掉)

 

 

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <set>
  7 #include <map>
  8 
  9 #define LL long long
 10 using namespace std;
 11 const int maxn = 100005;
 12 
 13 int n,m,q;
 14 char c;
 15 int x,y,z;
 16 int sum;
 17 struct segment_tree
 18     int l,r,col;
 19     int lazy;
 20 tree[maxn*4];
 21 
 22 void pushup(int nod)
 23     tree[nod].col = tree[nod<<1].col | tree[(nod<<1)+1].col;
 24     return ;
 25 
 26 
 27 void pushdown(int nod)
 28     tree[nod].lazy = 0;
 29     tree[nod<<1].lazy = 1;
 30     tree[(nod<<1)+1].lazy = 1;
 31     tree[nod<<1].col = tree[nod].col;
 32     tree[(nod<<1)+1].col = tree[nod].col;
 33     return ;
 34 
 35 
 36 void build(int nod,int l,int r)
 37     tree[nod].l = l;
 38     tree[nod].r = r;
 39     tree[nod].col = 1; //这个初始化根据具体题目而决定
 40     tree[nod].lazy = 0;
 41     if (l == r)
 42         return ;
 43     int mid = (tree[nod].l + tree[nod].r)>>1;
 44     build(nod<<1,l,mid);
 45     build((nod<<1)+1,mid+1,r);
 46     pushup(nod);
 47 
 48 
 49 void updata(int nod,int l,int r,int val)
 50     if (tree[nod].l == l && tree[nod].r == r)
 51         tree[nod].col = 1<<(val-1);
 52         tree[nod].lazy = 1;
 53         return ;
 54     
 55     if (tree[nod].col == 1<<(val-1))  // 如果颜色一样,不用更新
 56         return ;
 57     if (tree[nod].lazy)
 58         pushdown(nod);
 59     int mid = (tree[nod].l + tree[nod].r) >> 1;
 60     if (r <= mid)
 61         updata(nod<<1,l,r,val);
 62     
 63     else if (l>mid)
 64         updata((nod<<1)+1,l,r,val);
 65     
 66     else 
 67         updata(nod<<1,l,mid,val);
 68         updata((nod<<1)+1,mid+1,r,val);
 69     
 70     pushup(nod);
 71 
 72 
 73 void querry(int nod,int l,int r)
 74     if (tree[nod].l == l && tree[nod].r == r)
 75         sum |= tree[nod].col;
 76         return ;
 77     
 78     if (tree[nod].lazy)
 79         pushdown(nod);
 80     
 81     int mid = (tree[nod].l + tree[nod].r) >> 1;
 82     if (r <= mid)
 83         querry(nod<<1,l,r);
 84     
 85     else if (l>mid)
 86         querry((nod<<1)+1,l,r);
 87     
 88     else 
 89         querry(nod<<1,l,mid);
 90         querry((nod<<1)+1,mid+1,r);
 91     
 92 
 93 
 94 int Ans(int sum)
 95     int ans = 0;
 96     while (sum)
 97         if (sum & 1)
 98             ans++;
 99         
100         sum = (sum>>1);
101     
102     return ans;
103 
104 
105 
106 int main()
107     scanf("%d%d%d",&n,&m,&q);
108     build(1,1,n);
109     getchar();
110     for(int i=1;i<=q;i++)
111     
112         scanf("%s",&c);
113         if(c==C)
114         
115             scanf("%d%d%d",&x,&y,&z);
116             if(x>y)swap(x,y);
117             getchar();
118             updata(1,x,y,z);
119         
120         else
121         
122             scanf("%d%d",&x,&y);
123             getchar();
124             sum=0;
125             if(x>y)swap(x,y);//x可能>y
126             querry(1,x,y);
127             cout<<Ans(sum)<<endl;;
128         
129     
130     return 0;
131 

 

以上是关于Count Color (线段树区间染色?二进制状态压缩)的主要内容,如果未能解决你的问题,请参考以下文章

[日常摸鱼][poj2777]Count Color-线段树

ZOJ 1610 Count the Colors (线段树成段更新)

POJ - 2777——Count Color(懒标记线段树二进制)

HDU1199 Color the Ball (线段树合并+离散化经典)

POJ 2777 Count Color (线段树成段更新+二进制思维)

POJ2777 线段树区间染色问题