问题描述

第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;//初始没有颜色 都是0build(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;//清空ansquery(1, l, r);int res = ans.count();//ans.count()返回ans中有几位是1printf("%d\n", res);}}if(!flag) puts("This is a boring game!");return 0;
}

转载于:https://www.cnblogs.com/yu-xing/p/10853684.html

第十四届中北大学ACM程序设计竞赛 J.ZBT的游戏相关推荐

  1. 第十四届华中科技大学程序设计竞赛--J Various Tree

    链接:https://www.nowcoder.com/acm/contest/106/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...

  2. 第十五届浙江省ACM程序设计竞赛小记

    因为前段时间一直在找实习的缘故,比赛前几乎没怎么练习,所以对这场比赛本不抱太大希望. 早上7.30在学校门口集合,坐着大巴去浙江大学紫金港校区比赛,这是第二年到浙江大学参加ACM竞赛,心情依旧是很欢悦 ...

  3. 第十四届华中科技大学程序设计竞赛 B Beautiful Trees Cutting【组合数学/费马小定理求逆元/快速幂】...

    链接:https://www.nowcoder.com/acm/contest/106/B 来源:牛客网题目描述 It's universally acknowledged that there're ...

  4. 河南省第十四届ICPC大学生程序设计竞赛

    题目链接 https://ac.nowcoder.com/acm/contest/58860 分组背包问题 有 N N N 组物品和一个容量是 V V V 的背包. 每组物品有若干个,同一组内的物品最 ...

  5. A ZJH and Monkeys 第十四届华中科技大学程序设计竞赛

    链接: https://www.nowcoder.com/acm/contest/106/A 来源:牛客网 It's universally acknowledged that there're in ...

  6. 第十四届华中科技大学程序设计竞赛-L—Fresh Air,bfs拓展,倒着bfs

    链接: https://www.nowcoder.com/acm/contest/106/L 来源:牛客网 It's universally acknowledged that there're in ...

  7. 2018年湖南省第十四届大学生计算机程序设计竞赛 CSU 2164: 2018

    题目传送门 不会自己推,比赛现场找规律. 代码: #include<bits/stdc++.h> using namespace std;typedef long long LL; con ...

  8. 第十五届北京师范大学程序设计竞赛决赛(网络同步赛) B lca水 D 思维,找规律...

    第十五届北京师范大学程序设计竞赛决赛(网络同步赛) B. Borrow Classroom 题意:一棵树,点 1为根,一个人从点 b到 点 c再到点 1,第二个人从点 a出发,问第二个人能否截住第一个 ...

  9. 2022年第十四届全国大学生数学竞赛

    11.12非延迟地区开赛啦,小编为大家整理了2022年第十四届全国大学生数学竞赛真题加标答 希望帮到大 家   大学竞赛君自做答案90+,延迟地区的小伙伴也可以辅导

最新文章

  1. 公路病害检测有了“智慧眼”,思谋AI“助力”广东省高速公路
  2. 根据centos系统启动过程定位故障位置
  3. CodeForces - 555A Case of Matryoshkas(思维)
  4. 14行代码AC——习题5-4 交换学生(Foreign Exchange, UVa 10763)——解题报告
  5. java的集合应用_Java之集合类应用总结
  6. finditerable 转list_java – 通过拆分和运行将ListenableFuture转换为Iterable
  7. linux rm 某个时间以前,(转)linux的一个find命令配合rm删除某天前的文件
  8. NHibernate 3.3
  9. java实现堆栈排序_Java代码为例讲解堆的性质和基本操作以及排序方法
  10. Python算法教程:找出图的连通分量
  11. 安卓代码怎么设置省电模式_Android手机省电加速设置大全
  12. [GAMIT/GLOBK学习笔记]globk_comb.cmd/glorg_comb.cmd文件详解
  13. apache与tomcat动静分离
  14. java中画幅相机推荐_中画幅数码相机推荐
  15. JavaWeb基础学习一无框架项目小练习
  16. EAI_BOT越登智能车
  17. chrome调试js
  18. Matlab画图彩色变黑白
  19. html在图片上半透明磨砂,有没有办法在HTML内容上实现磨砂玻璃浮动div(类IO7)...
  20. java 两个list合并

热门文章

  1. stable-baselines3学习之Logger
  2. Windows的cmd中cd指令切换路径
  3. 受用一生的高效 PyCharm 使用技巧(三)
  4. 分椰子c语言csdn,水手分椰子——迭代法、递归解题
  5. [渝粤教育] 中国地质大学 城镇规划 复习题 (2)
  6. 用js来完成一个赛车的小游戏
  7. 【手册】如何编译/修改三星手机Rom(三)
  8. 排序算法学习整理一(冒泡)
  9. Google 协作平台 博客和内容管理系统 跟踪代码设置 GA谷歌分析
  10. listview控件Android,Android中ListView控件的简单使用