POJ-2777Count Color 线段树+位移
这道题对于我这样的初学者还是有点难度的不过2遍A了还是很开心,下面说说想法……
Count Color
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 40302 Accepted: 12161
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 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:
1. “C A B C” Color the board from segment A to segment B with color C.
2. “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 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
Sample Output
2
1
题目大意:
往画板上染色,画板长L(1<=L<=100000)颜色共有T种(1<=T<=30)给你O条操作(1<=O<=100000)操作分两种
(1)“C A B C”操作C:将【A,B】染成C色(开始时,画板都是颜色1)
(2)“P A B”操作P:【A,B】范围内颜色种数
(此题有个蛋疼的地方,读入的AB可能顺序颠倒...也是略坑)
这道题用位移来做,如果染成t种颜色,就把颜色左移t-1位,位移运算在这道题里完美展现,所以以后还是得注重这种表示方法,了解多了,自然做题顺畅
用二进制表示对应的区间涂了第几种颜色,这样每个区间除了延迟标记外,可以再开一个数组统计当前涂了哪几种颜色。这样就和一般的线段树一样了。
(这种思想值得学习)
最后再统计一下1的数目
下面是代码:
//这波位移非常的nice啊!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxl 100001
int color[maxl<<2]={0},sum[maxl<<2]={0};
void updata(int now)
{
sum[now]=sum[now<<1]|sum[now<<1|1];
}//or
void pushdown(int now)
{
if (color[now]!=0)
{
color[now<<1]=color[now<<1|1]=color[now];
sum[now<<1]=color[now];
sum[now<<1|1]=color[now];
color[now]=0;
}
}
void build(int l,int r,int now)
{
color[now]=1;
if (l==r) return;
int mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,now<<1|1);
updata(now);
}
void change(int L,int R,int l,int r,int now,int newcolor)
{
if (L<=l && R>=r)
{
color[now]=1<<(newcolor-1);
sum[now]=color[now];
return;
}//位移表示颜色
int mid=(l+r)>>1;
pushdown(now);
if (L<=mid)
change(L,R,l,mid,now<<1,newcolor);
if (R>mid)
change(L,R,mid+1,r,now<<1|1,newcolor);
updata(now);
}
int query(int L,int R,int l,int r,int now)
{
if (L<=l && R>=r)
return sum[now];
pushdown(now);
int mid=(l+r)>>1;
int ans=0;
if (L<=mid)
ans=ans|query(L,R,l,mid,now<<1);
if (R>mid)
ans=ans|query(L,R,mid+1,r,now<<1|1);//要对结果取or
return ans;
}
int main()
{
int l,t,o;
while(~scanf("%d%d%d",&l,&t,&o))
{
build(1,l,1);
for (int i=1; i<=o; i++)
{
char command[2];
int left,right,data;
scanf("%s",&command);
if (command[0]=='C')
{
scanf("%d%d%d",&left,&right,&data);
if (left>right)
{
int temp=left;
left=right;
right=temp;
}
change(left,right,1,l,1,data);
}
else
{
scanf("%d%d",&left,&right);
if (left>right)
{
int temp=left;
left=right;
right=temp;
}
int ans=query(left,right,1,l,1);
int answer=0;
while (ans>0)
{
if (ans & 1)
answer++;
ans=ans>>1;
}//这里表示颜色数
printf("%d\n",answer);
}
}
printf("\n");
}
return 0;
}
POJ-2777Count Color 线段树+位移的更多相关文章
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- Buy Tickets POJ - 2828 思维+线段树
Buy Tickets POJ - 2828 思维+线段树 题意 是说有n个人买票,但是呢这n个人都会去插队,问最后的队列是什么情况.插队的输入是两个数,第一个是前面有多少人,第二个是这个人的编号,最 ...
- poj 2777 Count Color(线段树)
题目地址:http://poj.org/problem?id=2777 Count Color Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- poj 2777 Count Color(线段树区区+染色问题)
题目链接: poj 2777 Count Color 题目大意: 给出一块长度为n的板,区间范围[1,n],和m种染料 k次操作,C a b c 把区间[a,b]涂为c色,P a b 查 ...
- poj 2777 Count Color - 线段树 - 位运算优化
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42472 Accepted: 12850 Description Cho ...
- POJ P2777 Count Color——线段树状态压缩
Description Chosen Problem Solving and Program design as an optional course, you are required to sol ...
- poj 2777 Count Color(线段树、状态压缩、位运算)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38921 Accepted: 11696 Des ...
- POJ 2777 Count Color(线段树之成段更新)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33311 Accepted: 10058 Descrip ...
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
随机推荐
- WPF标注装饰器
标注 在许多地方我们都会用到标注,比如在画图中: 在Office中: 在Foxit Reader中: 在Blend中: 等等. 简介 以前,因项目上需要做标注,简单找了一下,没发现适合要求的控件(包括 ...
- Flash Builder快捷键
代码助手:Ctrl+Space(简体中文操作系统是Alt+/)快速修正:Ctrl+1单词补全:Alt+/打开外部Java文档:Shift+F2 显示搜索对话框:Ctrl+H快速Outline:Ctrl ...
- java 12-5 StringBuffer的几个案例
1. 把数组拼接成一个字符串 public class StringBufferTest2 { public static void main(String[] args) { //定义一个数组 in ...
- 各种各样的hack。
http://itakeo.com/blog/2015/11/16/allhack/?none=123 Android Selector Hacks .selector:not(*:root) {} ...
- 携手K2 BPM,华住酒店完美实现“互联网+”转型
华住酒店集团,旗下6大品牌酒店,包括商旅品牌—禧玥酒店.全季酒店.星程酒店.汉庭酒店.海友酒店,以及度假品牌—漫心度假酒店.高端大气上档次一气呵成,2013年签约K2,携手成就美好生活. 演讲人:宋洪 ...
- C语言 预处理二(宏定义--#define)
//#define 宏定义(宏定义一般大写) //知识点一-->#define的作用域:从#define开始,从上往下,如果遇到#undef就到#undef处结束,如果没有就是作用于当前整个文件 ...
- C++函数内存占用
一个类的对象中是没有关于普通成员函数的指针的slot,只有成员变量还有虚表指针,类的成员函数的代码定义在PE文件的代码区,所以从程序加载时,就已经分配好了内存用于存放这些代码:代码运行时所需要的内存, ...
- 深入分析 Javascript 单线程
面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event l ...
- mvc control 请求两次问题
今天在做项目时,突然发现一个mvc 的control中action被执行了两次,最终发现是由于favicon.ico导致的.问题代码: <link rel="shortcut icon ...
- ubuntu上怎么设置默认python命令是执行python3而不是python2
来源:https://segmentfault.com/q/1010000003713912 alternatives这么好的机制用起来呀. shell里执行: sudo update-alterna ...