第十四届中北大学ACM程序设计竞赛 J.ZBT的游戏
问题描述
第14届中北大学程序设计竞赛来了,集训队新买了一大堆气球,气球一共有K种颜色(1<=K<=256),气球的颜色从1-K编号。
ZBT童心未泯,他发明了一种摆放气球的游戏,规则如下。
一排有N个桌子,每张桌子上只有一个气球插孔,即每张桌子最多只能放一个气球。编号分别为1-N(1<=N<=100000),每张桌子一开始是空的。现在对这张桌子要进行M次操作(1<=M<=100000),操作的种类一共有2种。
操作1:
操作指令格式: CHANGE L R C
操作含义:在编号为L至编号为R的桌子分别放置颜色为C的气球(如果这些桌子上曾经有气球,则取下原来的气球。因为每张桌子上只能放置一个气球)
操作2:
操作指令格式: QUERY L R
操作含义:输出编号为L到编号为R的桌子上的气球颜色种类数
现在他要求你写程序来完成他的操作,程序的输入输出见输入、输出描述
输入描述
第1行是三个整数N和M以及K,用空格隔开,分别代表桌子的个数、要进行操作指令的个数、以及气球的颜色总数。
接下来M行,每行一个操作指令,格式如上,保证指令中的1<=L<=R<=N, 1<=C<=K
输出描述
如果操作指令中有查询操作(操作2),那么对于每个操作2输出一行,该行中只有一个整数即为该查询操作的答案。
如果全部操作指令中都没有查询操作(操作2),那么请输出” This is a boring game!”(不含引号)
样例输入
10 20 5
QUERY 6 8
CHANGE 5 8 5
CHANGE 2 3 5
CHANGE 9 10 1
QUERY 9 9
QUERY 8 10
CHANGE 2 4 4
CHANGE 9 9 2
QUERY 2 2
CHANGE 8 10 1
CHANGE 6 9 3
CHANGE 10 10 2
QUERY 3 5
QUERY 6 8
QUERY 2 5
QUERY 5 5
QUERY 3 9
QUERY 4 10
CHANGE 5 8 1
QUERY 7 8
样例输出
0
1
2
1
2
1
2
1
3
4
1
题意:维护颜色序列,支持以下操作
- 区间覆盖(颜色修改)
- 区间查询颜色种类
前置技能:
- 线段树基本操作(区间覆盖、区间查询)
- 状态压缩思想
显然,如果是单点修改的话,等同于洛谷P1903 [国家集训队]数颜色 。有离线做法:CDQ+树状数组/带修莫队和 在线做法:树套树 等多种优雅解法(然而本人都不会)。
但是,因为本题有区间覆盖的操作,导致上述做法失效或转移复杂度过高。
所以该怎么做呢?
本题的操作都是区间操作,可以想到用线段树。观察到颜色种类只有256种,因此可以在每个线段树的结点上存储一个集合,表示这个结点代表的区间里出现颜色的种类。
维护时,区间覆盖还是打Lazytag。当某个区间被完全覆盖需要修改时,把集合中的元素清空,只存入当前修改的一种颜色。
每次递归并下传标记后,当前结点的颜色集合等于左右子节点的颜色集合的并集。
具体维护集合,可以用bitset或者用4个longlong类型变量(相当于手写bitset)。
这里每个结点开一个bitset<300> dat;
区间被完全覆盖,先把这个结点的颜色集合清空,即node[p].dat=0;然后集合里只有覆盖的这种颜色color,即node[p].dat[color]=1。
每次完成对左右儿子的修改后上传操作,当前结点的颜色集合等于左右子节点的颜色集合的并集,即node[p].dat=node[p<<1].dat|node[p<<1|1].dat 。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, k;
bitset<300> ans;//统计答案用
struct SegmentTree {
int l, r, tag;
bitset<300> dat;//相当于每个结点存储一个颜色集合
#define l(p) (node[p].l)
#define r(p) (node[p].r)
#define tag(p) (node[p].tag)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l(p)+r(p))>>1)
} node[N << 2];
void build(int p, int l, int r) {
l(p) = l;
r(p) = r;
if(l == r) return;//初始没有颜色 都是0
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
}
void update(int p, int v) {//结点p被颜色v完全覆盖
tag(p) = v;
node[p].dat = 0;//清空集合
node[p].dat[v] = 1;//集合里只有颜色v
}
void pushdown(int p) {//下传结点p标记
if(tag(p)) {
update(ls(p), tag(p));//更新左右结点
update(rs(p), tag(p));
tag(p) = 0;//清空标记
}
}
void change(int p, int L, int R, int v) {
if(l(p) > R || r(p) < L) return;//修改区间与该节点表示区间没有交集
if(L <= l(p) && r(p) <= R) return update(p, v);//该节点被完全覆盖
pushdown(p);//下传标记
change(ls(p), L, R, v);//修改左右儿子结点
change(rs(p), L, R, v);
node[p].dat = node[ls(p)].dat | node[rs(p)].dat;//当前颜色集合等于左右儿子的集合的并集
}
void query(int p, int L, int R) {//查询时同理
if(l(p) > R || r(p) < L) return;
if(L <= l(p) && r(p) <= R) {
ans = ans | node[p].dat;//这里ans是全局变量
return;
}
pushdown(p);
query(ls(p), L, R);
query(rs(p), L, R);
node[p].dat = node[ls(p)].dat | node[rs(p)].dat;
}
int main() {
scanf("%d%d%d", &n, &m, &k);
build(1, 1, n);
char op[10];
int l, r, c;
bool flag = false;
while(m--) {
scanf("%s%d%d", op, &l, &r);
if(op[0] == 'C') {
scanf("%d", &c);
change(1, l, r, c);
} else if(op[0] == 'Q') {
flag = true;
ans = 0;//清空ans
query(1, l, r);
int res = ans.count();//ans.count()返回ans中有几位是1
printf("%d\n", res);
}
}
if(!flag) puts("This is a boring game!");
return 0;
}
第十四届中北大学ACM程序设计竞赛 J.ZBT的游戏的更多相关文章
- 第十四届华中科技大学程序设计竞赛 J Various Tree【数值型一维BFS/最小步数】
链接:https://www.nowcoder.com/acm/contest/106/J 来源:牛客网 题目描述 It's universally acknowledged that there'r ...
- 第十四届华中科技大学程序设计竞赛--J Various Tree
链接:https://www.nowcoder.com/acm/contest/106/J来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...
- 第十四届华中科技大学程序设计竞赛决赛同步赛 A - Beauty of Trees
A - Beauty of Trees 题意: 链接:https://www.nowcoder.com/acm/contest/119/A来源:牛客网 Beauty of Trees 时间限制:C/C ...
- 第十四届华中科技大学程序设计竞赛决赛同步赛 F Beautiful Land(01背包,背包体积超大时)
链接:https://www.nowcoder.com/acm/contest/119/F来源:牛客网 Beautiful Land 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1 ...
- 第十四届华中科技大学程序设计竞赛 K Walking in the Forest【二分答案/最小化最大值】
链接:https://www.nowcoder.com/acm/contest/106/K 来源:牛客网 题目描述 It's universally acknowledged that there'r ...
- 第十四届华中科技大学程序设计竞赛 C Professional Manager【并查集删除/虚点】
题目描述 It's universally acknowledged that there're innumerable trees in the campus of HUST. Thus a pro ...
- 第十四届华中科技大学程序设计竞赛 B Beautiful Trees Cutting【组合数学/费马小定理求逆元/快速幂】
链接:https://www.nowcoder.com/acm/contest/106/B 来源:牛客网 题目描述 It's universally acknowledged that there'r ...
- 第十四届华中科技大学程序设计竞赛 K--Walking in the Forest
链接:https://www.nowcoder.com/acm/contest/106/K来源:牛客网 题目描述 It’s universally acknowledged that there’re ...
- 第十四届华中科技大学程序设计竞赛决赛同步赛 Beautiful Land
It’s universally acknowledged that there’re innumerable trees in the campus of HUST.Now HUST got a b ...
随机推荐
- 新的开始 | Arthas GitHub Star 破万后的回顾和展望
一切新的开始,都始于一个里程碑. 2月20日上午,Java 开源诊断工具 Arthas 的 GitHub Star 突破10000,距离开源后的第一个Release 版发布仅 147 天. 从中,我们 ...
- Centos rpm 卸载
参考网址: http://blog.sina.com.cn/s/blog_7d12ba3f01014gxv.html
- JS获取页面,元素,窗口和返回页面,元素,窗口的宽高以及滚动值
jquery获取页面,元素,窗口的宽高以及滚动值 //获取浏览器显示区域(可视区域)的高度 : $(window).height(); //获取浏览器显示区域(可视区域)的宽度 : $(window) ...
- JavaScript中this的指向(转载)
转载自:http://www.cnblogs.com/dongcanliang/p/7054176.html 前言 this 指向问题是入坑前端必须了解知识点,现在迎来了ES6时代,因为箭头函数的出现 ...
- Web基础了解版06-Jsp
Jsp Jsp全称Java Server Pages,也就是在我们JavaWeb中的动态页面. Jsp能够以HTML页面的方式呈现数据,是一个可以嵌入Java代码的HTML. Jsp其本质就是一个Se ...
- mybatis深入理解(六)-----MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及 ...
- Xshell 、PuTTY 复制文件到Linux
一.使用Xshell 在linux下下载一个需要安装一个工具lrzsz包: [root@localhost home] # yum install -y lrzsz 从windows上传文件到linu ...
- Java问题解读系列之IO相关---Java深拷贝和浅拷贝
前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...
- 洛谷P2327 [SCOI2005]扫雷 [2017年5月计划 清北学堂51精英班Day1]
P2327 [SCOI2005]扫雷 题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一 ...
- 考试总结 模拟28(W)
心得: 状态极差,都怪放假,上一套的T3没改完,今天考试没有一点状态,开学恐惧症.(不恐惧作业或一调但还是很茫然) T1能A掉实在是意外,杂题T1没做过,可能是人品守恒,(丢了钱今天才发现以后一定锁柜 ...