POJ:2777-Count Color(线段树+状压)
2018-01-10 20:35
399 查看
Count Color
Time Limit: 1000MS Memory Limit: 65536KDescription
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, … L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:
“C A B C” Color the board from segment A to segment B with color C.
“P A B” Output the number of different colors painted between segment A and segment B (including).
In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, … color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your.
Input
First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains “C A B C” or “P A B” (here A, B, C are integers, and A may be larger than B) as an operation defined previously.Output
Ouput results of the output operation in order, each line contains a number.Sample Input
2 2 4C 1 1 2
P 1 2
C 2 2 2
P 1 2
Sample Output
21
解题心得:
一看就是线段树,但是还加了状压,每一段区间用一个二进制来表示其涂抹情况,假如二进制的第一位为1代表第一种颜色涂抹了,然后父节点等于两个子节点的状态或起来,询问的区间用0去线段树中或,然后数1的个数就行了。区间更新的时候lazy标记一下,但是要注意的是颜色是直接覆盖。
读题眼贱了一下,没看到给的left端和right端可能是交换的,然后一直Runtime Error,怀疑人生啊。
#include<stdio.h> #include<cstring> #include<iostream> using namespace std; const int maxn = 1e6+100; struct Bitree { int l,r; int co; } bitree[maxn<<2]; int lazy[maxn<<2]; int n,a,b,c,o,t,ans; void updata(int rt)//向上更新 { bitree[rt].co = (bitree[rt<<1].co)|(bitree[rt<<1|1].co);//字节点或起来 } void build_tree(int rt,int l,int r)//先初始化一棵树 { bitree[rt].l = l; bitree[rt].r = r; bitree[rt].co |= 2; if(r == l) return ; int mid = (l + r)>>1; build_tree(rt<<1,l,mid); build_tree(rt<<1|1,mid+1,r); updata(rt); } void pushdown(int rt)//向下更新,注意lazy标记的转移方式就可以了 { if(bitree[rt].l == bitree[rt].r || !lazy[rt]) return ; bitree[rt<<1].co = bitree[rt<<1|1].co = 0; bitree[rt<<1].co |= (1<<lazy[rt]); bitree[rt<<1|1].co |= (1<<lazy[rt]); lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; lazy[rt] = 0; } void make_lazy(int rt,int l,int r,int L,int R)//区间更新,lazy标记 { pushdown(rt); if(l == L && r == R) { lazy[rt] = c; bitree[rt].co = 0; bitree[rt].co |= (1<<c); return ; } int mid = (L + R) >> 1; if(mid >= r) make_lazy(rt<<1,l,r,L,mid); else if(mid < l) make_lazy(rt<<1|1,l,r,mid+1,R); else { make_lazy(rt<<1,l,mid,L,mid); make_lazy(rt<<1|1,mid+1,r,mid+1,R); } updata(rt); } void query(int rt,int l,int r,int L,int R) { pushdown(rt); if(L == l && R == r) { ans |= bitree[rt].co;//查询的时候用ans去将线段树中的状态或出来 return ; } int mid = (L + R) >> 1; if(mid >= r) query(rt<<1,l,r,L,mid); else if(mid < l) query(rt<<1|1,l,r,mid+1,R); else { query(rt<<1,l,mid,L,mid); query(rt<<1|1,mid+1,r,mid+1,R); } updata(rt); } int SUM(int x) { int sum = 0; while(x) { if(x&1) sum++; x >>= 1; } return sum; } int main() { while(cin>>n>>t>>o) { memset(lazy,0,sizeof(lazy)); memset(bitree,0,sizeof(bitree)); build_tree(1,1,n); while(o--) { char s[10]; scanf("%s",s); if(s[0] == 'C') { scanf("%d%d%d",&a,&b,&c); if(a>b)//注意交换啊,坑死了 swap(a,b); make_lazy(1,a,b,1,n); } else if(s[0] == 'P') { ans = 0; scanf("%d%d",&a,&b); if(a>b) swap(a,b); query(1,a,b,1,n); ans = SUM(ans);//数最终有多少个1的个数 printf("%d\n",ans); } } } return 0; }
相关文章推荐
- POJ 2777 Count Color(线段树 + 状态压缩)
- POJ 2777 Count Color 线段树
- POJ 2777 Count Color (线段树 区间覆盖染色问题)
- 【线段树】 POJ 2777 Count Color
- POJ 2777 Count Color 线段树区间更新位运算
- poj2777--Count Color(线段树,二进制转化)
- hdu5023A Corrupt Mayor's Performance Art(线段树+位运算) poj 2777Count Color(线段树+位运算)
- POJ 2777 Count Color(线段树区间更新)
- poj 2777 染色线段树 count color
- poj 2777 -- Count Color ( 线段树 )
- POJ 2777 Count Color 线段树区间更新位运算
- POJ 2777 Count Color 线段树染色问题+位运算表示状态
- poj 2777 Count Color(线段树区间修改)
- POJ训练计划2777_Count Color(线段树/成段更新/区间染色)
- POJ 2777 Count Color (线段树)
- POJ 2777Count Color (线段树区间更新 + 位运算压缩)
- poj 2777 Count Color (线段树区间更新)
- poj 2777 Count Color(线段树 Lazy-Tag思想 成段更新+区间统计)
- [POJ 2777]Count Color(线段树)
- poj 2777 Count Color(线段树区间更新)