poj2777( Count Color)

题目地址:Count Color

题目大意:

给一个划分为L的线段染色,有两种操作,一种C操作 给定l,r区间染色为val。另一种操作P 查询l,r区间的颜色有多少种。

解题报告:

线段树,区间更新。

这题的lazy 表示该区间颜色种类,如果单色则为“1”,如果多色为”0“。tag 代表该区间的哪一种颜色。如果修改区间的颜色时,判断修改的颜色和该区间的颜色是否相同,相同的话就return,如果直接找到该区间,直接lazy赋值为”1“,tag 赋值为”v“,不用往下递归,因为该区间包含下面的子区间的单色,所以查询的时候,只需要看从根区间往下递归,只要遇到单色区间,就说明往下的子区间也就一定是该颜色。

代码:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <string>
  8 #include <bitset>
  9 #include <vector>
 10 #include <queue>
 11 #include <stack>
 12 #include <cmath>
 13 #include <list>
 14 #include <map>
 15 #include <set>
 16 using namespace std;
 17 /***************************************/
 18 #define ll long long
 19 #define int64 __int64
 20 /***************************************/
 21 const int INF = 0x7f7f7f7f;
 22 const double eps = 1e-8;
 23 const double PIE=acos(-1.0);
 24 const int d1x[]= {0,-1,0,1};
 25 const int d1y[]= {-1,0,1,0};
 26 const int d2x[]= {0,-1,0,1};
 27 const int d2y[]= {1,0,-1,0};
 28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
 29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
 30 /***************************************/
 31 void openfile()
 32 {
 33     freopen("data.in","rb",stdin);
 34     freopen("data.out","wb",stdout);
 35 }
 36 /**********************华丽丽的分割线,以上为模板部分*****************/
 37 const int M=100100;
 38
 39 struct tree
 40 {
 41     int left,right;
 42     int lazy,tag;
 43 } node[M*4];
 44
 45 int cnt;
 46 int p[31];
 47 void build__tree(int id,int l,int r)
 48 {
 49     int mid=(l+r)/2;
 50     node[id].lazy=1;
 51     node[id].tag=1;
 52     node[id].left=l;
 53     node[id].right=r;
 54     if (l==r)
 55         return ;
 56     build__tree(id*2,l,mid);
 57     build__tree(id*2+1,mid+1,r);
 58 }
 59 void updata(int id,int l,int r,int v)
 60 {
 61     int mid=(node[id].left+node[id].right)/2;
 62     if (node[id].left==l&&node[id].right==r)
 63     {
 64         node[id].lazy=1;
 65         node[id].tag=v;
 66         return ;
 67     }
 68     if (node[id].tag==v&&node[id].lazy)
 69         return ;
 70     if (node[id].lazy)
 71     {
 72         node[id].lazy=0;
 73         updata(id*2,node[id].left,mid,node[id].tag);
 74         updata(id*2+1,mid+1,node[id].right,node[id].tag);
 75     }
 76     if (r<=mid)
 77         updata(id*2,l,r,v);
 78     else if (l>mid)
 79         updata(id*2+1,l,r,v);
 80     else
 81     {
 82         updata(id*2,l,mid,v);
 83         updata(id*2+1,mid+1,r,v);
 84     }
 85 }
 86 void query(int id,int l,int r)
 87 {
 88     int mid=(node[id].left+node[id].right)/2;
 89     if (node[id].lazy)
 90     {
 91         p[node[id].tag]=1;
 92         return;
 93     }
 94     if (r<=mid)
 95         query(id*2,l,r);
 96     else if (l>mid)
 97         query(id*2+1,l,r);
 98     else
 99     {
100         query(id*2,l,mid);
101         query(id*2+1,mid+1,r);
102     }
103 }
104 int main()
105 {
106     int l,t,o;
107     while(scanf("%d%d%d",&l,&t,&o)!=EOF)
108     {
109         int i,j;
110         build__tree(1,1,l);
111         while(o--)
112         {
113             char c;
114             int x,y,val;
115             getchar();
116             scanf("%c",&c);
117             if (c==‘C‘)
118             {
119                 scanf("%d%d%d",&x,&y,&val);
120                 if (x>y)
121                     swap(x,y);
122                 updata(1,x,y,val);
123             }
124             if (c==‘P‘)
125             {
126                 cnt=0;
127                 memset(p,0,sizeof(p));
128                 scanf("%d%d",&x,&y);
129                 if (x>y)
130                     swap(x,y);
131                 query(1,x,y);
132                 for(int i=1;i<31;i++)
133                     if (p[i])
134                         cnt++;
135                 printf("%d\n",cnt);
136             }
137         }
138
139     }
140     return 0;
141 }
142
143 /*
144 2 2 100
145 C 1 1 2
146 P 1 2
147 C 2 2 2
148 P 1 2
149 C 2 2 2
150 P 1 2
151 C 1 1 2
152 P 1 2
153 C 1 2 2
154 P 1 2
155 C 1 2 1
156
157 5 3 1000
158 C 2 3 2
159 C 2 4 3
160 C 3 5 2
161 C 2 3 1
162 C 1 3 2
163 P 1 5
164
165 5 3 1000
166 P 1 5
167 C 2 3 2
168 P 1 5
169 C 2 4 3
170 P 1 5
171 C 3 5 2
172 P 1 5
173 C 2 3 1
174 P 1 5
175 C 1 3 2
176 P 1 5
177 C 4 4 3
178 P 1 5
179 */

时间: 2024-10-12 08:12:04

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>

poj2777 Count Color 2011-12-20

Count Color Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 23937Accepted: 7078 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

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 2777 Count Color(线段树区间修改)

题目链接:http://poj.org/problem?id=2777 题目意思:就是问你在询问的区间里有几种不同的颜色 思路:这题和一般的区间修改差不多,但是唯一不同的就是我们要怎么计算有种颜色,所以这时候我们就需要把延时标记赋予不同的意义,当某段区间有多种颜色时就赋值为-1,当为一种颜色时就把它赋值为这个颜色的号数.这儿我们要怎么统计询问区间不同的颜色数叻,为了不重复计算同一种颜色,那么我们就需要用一个数组来标记计算过的颜色,当我们下次遇到时就不需要再次计算了.... 代码核心处就在计数那儿

POJ 2777 Count Color

C - Count Color Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2777 Appoint description:  System Crawler  (2015-07-22) Description Chosen Problem Solving and Program design as an optional cours

poj 2777 Count Color (成段更新+区间求和)

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

PKU 2777 Count Color (线段树区间更新)

题意: 给你三个数:L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000),表示有一长度为L的板(1~L), 有T种颜色(1~T),然后有O个操作,初始板1~L的颜色为1,"C A B C"表示在区间A,B图上C颜色, "P A B" 表示询问 A,B区间有几种不同的颜色. #include <stdio.h> #include <iostr

poj 2777 Count Color【线段树段更新】

题目:poj 2777 Count Color 题意:给出一段1 * n 的栅栏,有两种操作,第一种:把 l -- r 全部染成同一颜色t,第二种,查询 l---r 一共有多少种颜色. 分类:线段树 分析:我们可以给每个节点加一个标记,标记当前节点是否只有一种颜色,然后对只有一种颜色的节点如果要染色的话,那么他会变成几种颜色的,这时候记得向下更新一次就好,统计的时候统计节点有单个颜色的颜色就好. 代码: #include <cstdio> #include <cstring> #i

poj 2777 Count Color (线段树区间更新)

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