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单位之间的 ...
随机推荐
- 第51课 C++对象模型分析(下)
1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...
- AC日记——潜伏者 洛谷 P1071 (模拟)
题目描述 R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原 ...
- hydra爆破用法
-R 根据上一次进度继续破解 -S 使用SSL协议连接 -s 指定端口 -l 指定用户名 -L 指定用户名字典(文件) -p 指定密码破解 -P 指定密码字典(文件) -e 空密码探测和指定用户密码探 ...
- Pro Git(中文版)
Pro Git(中文版) 返回 Git @ OSC 目录 1.起步 1.1 关于版本控制 1.2 Git 简史 1.3 Git 基础 1.4 安装 Git 1.5 初次运行 Git 前的配置 1.6 ...
- 用yo命令创建项目
1,npm install -g yo 安装yeoman 2,npm install -g generator-webapp 安装项目脚手架(生成器) 如果安装angular的项目后面则是genera ...
- 细说git merge & git rebase
git merge和git rebase两个都是用来合并两个分支用的,在使用过程中,这两个概念容易混淆. 在此,对这两个git技巧的用法进行详细描述,希望能帮助一些热爱git的朋友. -------- ...
- WMI入门
转:http://www.cnblogs.com/ceachy/archive/2013/03/21/WMI_What.html WMI入门(一):什么是WMI WMI出现至今已经二十多年了,但很多人 ...
- C语言 文件操作1--二进制文件与文本文件
//写文件两种方式(文本文件和二进制文件) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h&g ...
- 一段后台C#查询SQL Server数据库代码
using System; using System.Data; using System.Collections.Generic; using System.Linq; using System.W ...
- Python自动化测试 (二) ConfigParser模块读写配置文件
ConfigParser 是Python自带的模块, 用来读写配置文件, 用法及其简单. 直接上代码,不解释,不多说. 配置文件的格式是: []包含的叫section, section 下有op ...