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 (线段树合并+离散化经典)