P1558 色板游戏
P1558 色板游戏
题目背景
阿宝上学了,今天老师拿来了一块很长的涂色板。
题目描述
色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格。并从左到右标记为1, 2, ... L。
现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:
"C A B C" 指在A到 B 号方格中涂上颜色 C。
"P A B" 指老师的提问:A到 B号方格中有几种颜色。
学校的颜料盒中一共有 T 种颜料。为简便起见,我们把他们标记为 1, 2, ... T. 开始时色板上原有的颜色就为1号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?
输入输出格式
输入格式:
第一行有3个整数 L (1 <= L <= 100000), T (1 <= T <= 30) 和 O (1 <= O <= 100000)。 在这里O表示事件数。
接下来 O 行, 每行以 "C A B C" 或 "P A B" 得形式表示所要做的事情(这里 A, B, C 为整数, 可能A> B,这样的话需要你交换A和B)
输出格式:
对于老师的提问,做出相应的回答。每行一个整数。
错误日志: 1.第一次交了暴力 \(30\) 颗线段树 \(MLE\) 2. 后面换了个思路却忘记了题目有坑(以粗体标出)
Solution
这里要说一下 \(bitset\) 这个宝贝了(快 \(noip\) 了, 多运用 \(STL\) 节省时间)
支持位数很大的二进制运算, 自带压缩, 运算较快
简单来说就是一个可以有很多位的状压利器
这题很明显线段树, 用了 \(bitset\) 做状态说明: 第 \(i\) 位 为 \(1\) 代表此区间有这个颜色, 为 \(0\) 则没有
上传更新时使用或运算, 表示取并集(bitset很大一用处就是取状态很多的并集, 十分方便)
这是满足分配律的
修改打懒标记记录区间颜色, 改区间状态直接把 \(bitset\) 赋值为 \(0\) 然后确定颜色位修改为 \(1\) 即可
附: \(bitset\) 用法
声明n位bitset : bitset<n> b;
全部赋值为0 : b.reset();
为1 : b.set();
对第i位操作 : b[i] = 1/0;
一个bitset里1的个数 : num = b.count();
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<bitset>
typedef long long LL;
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 100019;
int num, numc, na;
#define lid (id << 1)
#define rid (id << 1) | 1
struct seg_tree{
int l, r;
int lazy;
bitset<39>b;
}tree[maxn << 2];
void pushup(int id){
tree[id].b = tree[lid].b | tree[rid].b;
}
void pushdown(int id){
if(tree[id].lazy){
int c = tree[id].lazy;
tree[lid].b.reset(), tree[rid].b.reset();
tree[lid].b[c] = 1, tree[rid].b[c] = 1;
tree[lid].lazy = tree[rid].lazy = c;
tree[id].lazy = 0;
}
}
void build(int id, int l, int r){
tree[id].l = l, tree[id].r = r;
if(l == r){
tree[id].b[1] = 1;
return ;
}
int mid = (l + r) >> 1;
build(lid, l, mid), build(rid, mid + 1, r);
pushup(id);
}
void update(int id, int val, int l, int r){
pushdown(id);
if(tree[id].l == l && tree[id].r == r){
tree[id].b.reset();
tree[id].b[val] = 1;
tree[id].lazy = val;
return ;
}
int mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)update(rid, val, l, r);
else if(mid >= r)update(lid, val, l, r);
else update(lid, val, l, mid), update(rid, val, mid + 1, r);
pushup(id);
}
bitset<39> query(int id, int l, int r){
pushdown(id);
if(tree[id].l == l && tree[id].r == r){
return tree[id].b;
}
int mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)return query(rid, l, r);
else if(mid >= r)return query(lid, l, r);
else return query(lid, l, mid) | query(rid, mid + 1, r);
}
int main(){
num = RD();numc = RD();na = RD();
build(1, 1, num);
char cmd;
for(int i = 1;i <= na;i++){
cin>>cmd;
int l = RD(), r = RD();
if(l > r)swap(l, r);
if(cmd == 'C'){
int x = RD();
update(1, x, l, r);
}
else printf("%d\n", (int)query(1, l, r).count());
}
return 0;
}
P1558 色板游戏的更多相关文章
- P1558 色板游戏 状压线段树
P1558 色板游戏 状压线段树 题面 洛谷P1558 每次不同颜色覆盖一段区间,每次询问一段区间有多少种颜色 因为颜色数\(T\)很小,使用二进制表示状态当前区间有那些颜色,二进制第\(i\)位表示 ...
- 洛谷P1558 色板游戏 [线段树]
题目传送门 色板游戏 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, .. ...
- 【luogu P1558 色板游戏】 题解
题目链接:https://www.luogu.org/problemnew/show/P1558 我知道三十棵线段树很暴力,可是我们可以状压啊. 颜色最多30,不会爆int 另外 吐槽评测机 #inc ...
- 洛谷P1558 色板游戏
题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, ... L.现在色板上只有 ...
- 线段树(压位)luogu P1558色板游戏
题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, ... L. 现在色板上只 ...
- Luogu P1558 色板游戏【线段树/状态压缩】By cellur925
题目传送门 今天非常想再看一遍霸王别姬想不进去题于是开始刷数据结构 注意到至多只有\(30\)种颜色,啊啊啊啊我一开始竟然想的不是状态压缩而是在线段树中存一个30大小的数组,这样每次更新的时候暴力循环 ...
- P1558 色板游戏 线段树+二进制状压
好,这个想法是我想拿去做HH的项链的.但是那个颜色有十万种...直接爆. 做这个倒是so easy 被两个地方坑了.1,a,b可能大小相反. 2,ask之前要down一波,我没down就挂了..... ...
- Luogu P1558 色板游戏
(此题与POJ2777重题) 为了加深对线段树的记忆,然后开始搞这道题. TM的WA了一下午就是发现x可能大于y(然而题目里说的还很清楚,我TM没看见) 这道题只需要在线段树的板子上改一些地方就可以了 ...
- 洛谷 P1558 色板游戏
洛谷 题解里面好像都是压位什么的, 身为蒟蒻的我真的不会, 所以就来谈谈我的30颗线段树蠢方法吧! 这题初看没有头绪. 然后发现颜色范围好像只有30: 所以,我就想到一种\(sao\)操作,搞30颗线 ...
随机推荐
- (第九周)Beta-1阶段成员贡献分
项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...
- IDEA下载插件超时的原因
setting中红框的对勾去掉就可以下载插件了
- 奔跑吧DKY——团队Scrum冲刺阶段-Day 6
今日完成任务 谭鑫:制作相应动画人物,并实现人物动画 黄宇塘:制作相应动画人物,并实现人物动画,制作背景图 赵晓海:制作相应动画人物,并实现人物动画 方艺雯:制作相应动画人物,并实现人物动画,编写博客 ...
- servlet几个常用的方法
servlet继承了HTTPServlet所以可以重写父类的方法,下面一 一介绍方法Dopost DoGet 比较常用不再介绍. 一.Init(),和Init(ServletConfig config ...
- java中的互斥锁和信号量的区别
互斥锁和信号量都是操作系统中为并发编程设计基本概念,互斥锁和信号量的概念上的不同在于,对于同一个资源,互斥锁只有0和1 的概念,而信号量不止于此.也就是说,信号量可以使资源同时被多个线程访问,而互斥锁 ...
- MongoDB中的数据导出为excel CSV 文件
1.打开命令行,进入我们所安装的mongodb路径下的bin文件夹 2.我们采用bin文件夹下的mongoexport方法进行导出, mongoexport -d myDB -c user -f _i ...
- Scrum Meeting Beta - 6
Scrum Meeting Beta - 6 NewTeam 2017/12/5 地点:主南201 任务反馈 团队成员 完成任务 计划任务 安万贺 完成了离线状态本地存储的读取Issue #133Pu ...
- testNg-build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <proje ...
- .NET 切面编程 PostSharp
目录 概念 实现方式 .Net平台的切面实现 PostSharp示例 概念 Aspect-Oriented Programming(AOP):想想OOP是不是有些熟悉,AOP翻译过来的意思就是面向切面 ...
- poj 3254(状态压缩DP)
poj 3254(状态压缩DP) 题意:一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相 ...