【POJ2777】Count Color(线段树)

以下是题目大意:

有水平方向上很多块板子拼成的墙,一开始每一块都被涂成了颜色1,有C和P两个操作,代表的意思是:
C X Y Z —— 从X到Y将板子涂成颜色Z
P X Y    —— 查询X到Y的板子共有多少种颜色

1 2 2 4         //有2块板子   两2颜色   4个询问
2 C 1 1 2
3 P 1 2
4 C 2 2 2
5 P 1 2

自己AC后上网查阅了许多别人的题解,看很多人用的什么“状态压缩”、“位运算”等等方法。感觉自己不会的知识还有很多。我用的方法是类似于hash的思想,每次将颜色查询时标记,由于这题的数据范围很小,不需要用离散化处理,所以比较好写。下面附上代码。

 1 /*********************************************/
 2 /* author: Desgard_Duan                      */
 3 /* motto : Everything is surprise for you!   */
 4 /*********************************************/
 5
 6 #include <iostream>
 7 #include <cstring>
 8 #include <cstdlib>
 9 #include <cstdio>
10 #include <cctype>
11 #include <cmath>
12 #include <algorithm>
13 #include <numeric>
14 #include <string>
15 #include <limits.h>
16 #include <vector>
17 #include <set>
18 #include <map>
19
20 using namespace std;
21
22 const int maxn = 100100;
23 int col[maxn << 2], ans = 0;
24 int Hash[50];
25
26 void pushDown (int rt) {
27     if (col[rt]) {
28         col[rt * 2] = col[rt * 2 + 1] = col[rt];
29         col[rt] = 0;
30     }
31 }
32
33 void build (int l, int r, int rt) {
34     col[rt] = 1;
35     if (l == r) return ;
36     int m = (l + r) / 2;
37     build (l, m, rt * 2);
38     build (m + 1, r, rt * 2 + 1);
39 }
40
41 void update (int L, int R, int c, int l, int r, int rt) {
42     if (L <= l && r <= R) {
43         col[rt] = c;
44         return ;
45     }
46     pushDown (rt);
47     int m = (l + r) / 2;
48     if (L <= m) update (L, R, c, l, m, rt * 2 );
49     if (m <  R) update (L, R, c, m + 1, r, rt * 2 + 1);
50 }
51
52 void query (int L, int R, int l, int r, int rt) {
53     if (col[rt]) {
54         if (Hash[col[rt]] == 0) {
55             ans ++;
56             Hash[col[rt]] = 1;
57         }
58         return ;
59     }
60     int m = (l + r) / 2;
61     if (m >= L) query (L, R, l, m, rt * 2);
62     if (m  < R) query (L, R, m + 1, r, rt * 2 + 1);
63 }
64
65 int main () {
66     int L, T, O, x, y, z;
67     char op[5];
68     while (~scanf ("%d%d%d", &L, &T, &O)) {
69         memset (col, 1, sizeof (col));
70         build (1, L, 1);
71         while (O --) {
72             scanf ("%s%d%d", op, &x, &y);
73             if (x > y) swap (x, y);
74             if (op[0] == ‘C‘) {
75                 scanf ("%d", &z);
76                 update (x, y, z, 1, L, 1);
77             } else {
78                 memset (Hash, 0, sizeof (Hash));
79                 ans = 0;
80                 query (x, y, 1, L, 1);
81                 printf ("%d\n", ans);
82             }
83         }
84     }
85     return 0;
86 }
时间: 2024-11-13 22:55:53

【POJ2777】Count Color(线段树)的相关文章

POJ2777 Count Color 线段树区间更新

题目描述: 长度为L个单位的画板,有T种不同的颜料,现要求按序做O个操作,操作分两种: 1."C A B C",即将A到B之间的区域涂上颜色C 2."P A B",查询[A,B]区域内出现的颜色种类 出现操作2时,请输出答案 PS:初始状态下画板颜色为1 一开始没有想那么好,用int整型位移来代替颜色,还是使用了最传统的bool color[来记录,可是不知道错在了哪里, #include<iostream> #include<cstdio>

POJ 2777 Count Color(线段树)

题目地址:POJ 2777 我去..延迟标记写错了.标记到了叶子节点上....这根本就没延迟嘛...怪不得一直TLE... 这题就是利用二进制来标记颜色的种类.然后利用或|这个符号来统计每个区间不同颜色种数. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h

POJ 2777 Count Color (线段树+位运算)

题意很简单了,对一个区间有两种操作: 1. "C A B C" Color the board from segment A to segment B with color C. //A~B涂上颜色C 2. "P A B" Output the number of different colors painted between segment A and segment B (including). //输出A~B间颜色的种类数 题目链接:http://poj.o

poj 2777 Count Color(线段树、状态压缩、位运算)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 38921   Accepted: 11696 Description 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.

poj 2777 count color 线段树

Description 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 d

POJ P2777 Count Color——线段树状态压缩

Description 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 d

POJ 2777 count color(线段树,lazy标记)

这里有一个思想:我们在更新的时候不必要更新到叶子节点,只要更新到当前区间包含线段树区间即可. 设计一个标志位,更新到此. A Simple Problem with Integers 也是一个类似的题目 设计两个函数 push_down 将结点信息传递到下层节点(inc, sub,) push_up      将下层节点信息反馈到上层(max,min,count) #include <map> #include <set> #include <queue> #inclu

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

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把

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 #in

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace