Mayor‘s posters(线段树染色)

2023-11-13

题目链接: Mayor’s posters


2023.4.13 更新了代码, 修复了错误的离散化长度, 已在代码中注出.


大致题意

有n个人依次贴海报, 第i个海报的范围是[li, ri]. 后面贴的海报会覆盖掉之前贴的海报.

问: 最终还能看到多少张海报.

解题思路

本题属于线段树维护区间染色类别的题目. 本题考察线段树的区间修改, 根节点查询.

这类题目的一大特点就是: 线段树内维护当前整个区间的值, 相当于当前区间维护的值是一个懒标记, 其子节点的值也都为当前节点的值, 若当前区间内部的子区间值不统一, 则需要递归分别给每个子区间赋值, 此时认为当前节点认为没有值即可, 这样在查询的时候, 如果访问到一整个区间都是相同值, 则直接返回即可, 反之需要递归处理.

特别的, 本题的实际数据范围推荐为1E5, 题目中的1E4会报RE

AC代码

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E5 + 10;
bool vis[N]; //标记是否已经出现过第i张海报
struct node {
    int l, r;
    int id; //id表示lazy标签, 也表示当前节点值. 
}t[N << 2];
vector<int> v; vector<pair<int, int> > area; //v为离散化数组, area存放海报区间
int find(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }

void pushdown(node& op, int id) { op.id = id; }
void pushdown(int x) {
    if (!t[x].id) return;
    pushdown(t[x << 1], t[x].id), pushdown(t[x << 1 | 1], t[x].id);
    t[x].id = 0; 
}
//因为线段树内部不维护任何数值, 所以也可以省去pushup这一操作.

void build(int l, int r, int x = 1) {
    t[x] = { l, r, 0 }; //id: 特别的, 如果0也是染色的点, 那么应初始化为-1
    if (l == r) return;
    int mid = l + r >> 1;
    build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
}

void modify(int l, int r, int c, int x = 1) {
    if (l <= t[x].l && r >= t[x].r) { pushdown(t[x], c); return; }
    pushdown(x);
    int mid = t[x].l + t[x].r >> 1;
    if (l <= mid) modify(l, r, c, x << 1);
    if (r > mid) modify(l, r, c, x << 1 | 1);
}

int ask(int x = 1) { 
    if (t[x].id) { //当前子树均为同一值, 没必要再递归下去了
        if (vis[t[x].id]) return 0;
        return vis[t[x].id] = 1;
    }
	if (t[x].l == t[x].r) return 0; //到叶子结点一定要结束递归
    
    return ask(x << 1) + ask(x << 1 | 1);
}

int main()
{
    int T; cin >> T; 
    while (T--) {
        v.clear(); v.push_back(-0x3f3f3f3f); //这里是为了离散化下标从1开始
        area.clear();
        int n; scanf("%d", &n);
        rep(i, n) {
            vis[i] = 0; //顺带初始化vis
            int l, r; scanf("%d %d", &l, &r);
            v.push_back(l), v.push_back(r);
            area.push_back({ l, r });
        }
        
        /* 离散化部分 */
        sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());
       
        /* 2023.4.13更新代码 BEGIN */
        int vlen = v.size();
   		rep(i, vlen - 1) if (v[i] - v[i - 1] != 1) v.push_back(v[i] - 1); //记为*

   		// 下面这行是之前错误的代码, 我们的离散化判别应扫描整个vector, 而不是只判断到n
   		// rep(i, n) if (v[i] - v[i - 1] != 1) v.push_back(v[i] - 1); //记为*
   		/* 2023.4.13更新代码 END */
   		
        sort(v.begin(), v.end());
        
        build(1, v.size() - 1); //因为我的v数组有个-INF, 所以实际的建树大小应为v.size()-1
        
        for (int i = 0; i < n; ++i) {
            int l = area[i].first, r = area[i].second;
            l = find(l), r = find(r);
            modify(l, r, i + 1); //个人习惯编号从1开始
        }
        printf("%d\n", ask());
    }
    return 0;
}

这里关于*部分加以解释: 这里是为了防止离散化之前区间不连续, 而错误的离散化导致离散化后区间连续的情况. 网上已经有很多大佬用大篇文章及样例说明过了, 这里就不再多赘述啦, 毕竟我也是刚学过来的. 向前辈们学习致敬!

kuangbin线段树专题点这里!!!

END

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mayor‘s posters(线段树染色) 的相关文章

  • 算法与数据结构(二十五)TopK问题:基于快排的Python模板

    首先 先写partition模板 def partition nums left right pivot nums left 初始化一个待比较数据 i j left right while i lt j while i
  • 算法题-简单系列-05-两个链表的第一个公共结点

    文章目录 1 题目 1 1 思路1 循环遍历 1 题目 输入两个无环的单向链表 找出它们的第一个公共结点 如果没有公共节点则返回空 1 1 思路1 循环遍历 使用两个指针N1 N2 一个从链表1的头节点开始遍历 我们记为N1 一个从链表2的
  • C语言,求取数组的序亏:已知一个整数数组,求出个数组中每个元素在整个 数组的排序。

    要求获取整数数组中每个元素的排序 可以使用以下方法 1 定义一个结构体数组 其中每个结构体包含数组元素的值和索引 2 遍历整数数组 将每个元素与其索引一起存储到结构体数组中 3 对结构体数组进行排序 按照元素的值进行升序排序 4 遍历排序后
  • 【C++】手撕string思路梳理

    目录 基本思路 代码实现 1 构建框架 2 构建函数重载 3 迭代器 4 遍历string 5 resetve 开空间 insert任意位置插入push back append 按顺序依次实现 6 erase删除 clear清除 resiz
  • c 关于数组几个查序程序

    1 查询某元素是否在数组中 int main void char i 10 2 1 7 2 10 5 2 0 1 4 10 10 1 3 1 0 8 char z 10 1 2 3 4 1 4 6 8 0 9 int zz 0 标志位 0
  • DS八大排序之冒泡排序和快速排序

    前言 前两期我们已经对 插入排序 直接插入排序和希尔排序 和 选择排序 直接选择排序和堆排序 进行了详细的介绍 这一期我们再来详细介绍一组排序 交换排序 即耳熟能详的冒泡排序和赫赫有名的快速排序 本期内容介绍 冒泡排序 快速排序 Hoare
  • 剑指 Offer(第2版)面试题 35:复杂链表的复制

    剑指 Offer 第2版 面试题 35 复杂链表的复制 剑指 Offer 第2版 面试题 35 复杂链表的复制 解法1 模拟 剑指 Offer 第2版 面试题 35 复杂链表的复制 题目来源 48 复杂链表的复刻 解法1 模拟 算法 复制原
  • 数据结构 数组与字符串

    介绍 数组的基础 定义和声明 基本定义 在C语言中 数组可以被定义为一系列相同类型的元素的集合 每个元素在内存中连续排列 可以通过索引 通常是从0开始的整数 来访问 数组的声明 数组在C语言中的声明包括元素类型 数组名和大小 例如 声明一个
  • List去重-使用distinctByKey方法根据对象的属性进行去重

    description 使用distinctByKey方法根据对象的属性进行去重 author zs date 2023 12 18 14 29 param keyExtractor return java util function Pr
  • leetcode 560. 和为 K 的子数组(优质解法)

    代码 class Solution public int subarraySum int nums int k int length nums length key 表示前缀和 value 表示个数 HashMap
  • 【数据结构和算法】 K 和数对的最大数目

    其他系列文章导航 Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一 题目描述 二 题解 2 1 方法一 双指针排序 三 代码 3 1 方法一 双指针排序 3
  • 面试150-13(Leetcode238除自身以外数组的乘积)

    代码 class Solution public int productExceptSelf int nums int n nums length int res new int n int product 1 int zerocnt 0
  • 回溯算法第零篇【递归、搜索与回溯】【回溯算法入门必看】

    本篇文章的目的 1 给小伙伴们对回溯算法中的名词进行解释 2 消除递归的恐惧 回溯是递归的一个分支 给小伙伴们一个建议 整篇文章都要看完 一字不漏 全是干货 注意 分析回溯的思想之前 我们得知道一个关系 递归包含搜索 搜索包含回溯 所以我们
  • 【数据结构和算法】 K 和数对的最大数目

    其他系列文章导航 Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一 题目描述 二 题解 2 1 方法一 双指针排序 三 代码 3 1 方法一 双指针排序 3
  • Leetcode 55 跳跃游戏

    题意理解 非负整数数组 nums 最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 需要跳到nums最后一个元素即为成功 目标 是否能够跳到最后一个元素 解题思路 使用贪心算法来解题 需要理解局部解和最优解的关系
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到
  • 搜索二叉树(BSTree)

    一 搜索二叉树的概念 二叉搜索树又称为做二叉排序树 二叉查找树 其要么是一棵空树 要么是一个满足以下性质的二叉树 若它的左子树不空 则左子树上所有结点的关键字均小于根结点关键字 若它的右子树不空 则右子树上所有结点的关键字均大于根结点关键字
  • 206.翻转链表

    翻转链表 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems re
  • 带头双向循环链表基础

    带头双向循环链表基础 销毁 销毁 void ListDestory ListNode phead void ListDestory ListNode phead assert phead ListNode cur phead gt next
  • 顺序表和链表基础

    定义动态的顺序表 typedef int SLDataType typedef struct Seqlist SLDataType array size t size size t capacity Seqlist 在顺序表中插入数据 bo

随机推荐

  • Tableau常用函数

    1 ABS number 返回给定数字的绝对值 ABS 7 7 ABS 字段 字段中包含的所有数字的绝对值 2 ATTR expression 如果它的所有行都有一个值 则返回该表达式的值 否则返回星号 会忽略 Null 值 其实维度也可以
  • JAVA_常用API-Math

    目录 前言 一 Math类 Max类的常用方法 例题 1 取绝对值 返回正数 输出结果为 2 向上或者向下取整 3 求指数次方 以及四舍五入 4 生成随机数random 范围是 0 0 1 0 0 0 1 0 总结 前言 本篇文章作为作者学
  • 我们人类与人工智能技术究竟是怎样的关系?

    图片来自pixabay com 来源 赛先生 撰文 爱德华 阿什福德 李 加州大学伯克利分校教授 责编 李珊珊 摘要 数字技术正在和人类文明协同进化 我们依赖技术而生存 技术也依赖我们 这种合作共生的趋势越来越明显 技术并不是所谓的 应用科
  • 解决:java -version,java,javac不是内部或外部命令,也不是可运行的程序 或批处理文件。

    命令行输入java java version javac都显示不是内部或外部命令 1 首先查看了自己的环境变量 经过学习确实都是环境变量出现问题 之前的环境变量都是 JAVA HOME bin 全部换成了绝对路径如 C Program Fi
  • 弃用http改用https的缘故,与密钥的使用,证书意义

    为何弃用http协议 在十几年前 我们的传输协议是http协议 为何到了如今改成了https协议呢 为了安全的考虑 在http协议中 我们的内容是透明的 不被保护的 在黑客等恶意分子的面前 信息极其任意被破译 让我们看看客户端如果使用htt
  • spring笔记1(基础(IoC控制反转、DI依赖注入)、整合Junit、整合web)

    目录 前言 1 spring框架概述 1 什么是spring 1 2 spring由来 1 3spring核心 1 4spring优点 1 5 spring体系结构 2入门案例 IoC 掌握 2 1 导入jar包 2 2 目标类 2 3 配
  • R中关于金融的包

    quantmod 数据和图形 TTR 技术分析 blooter 账户管理 FinancialInstrument 金融产品 quantstrast 策略模型 PerformanceAnalytics 表现分析 这些R包依然在发展中 有些还被
  • 原生js导出excel,并保留样式

    前端表格导出excel一般我们使用xlsx等插件导出 但如果想保留表格的样式导出的话 还需要再使用其他的插件才行 如要保留宽度 字体颜色 背景颜色等样式 这里可以直接使用简短的 原生js方法即可导出带样式的excel文件 直接上代码 原生表
  • 股票实时数据接口

    From http chenpeng info html 1058 做了一点股票分析数据准备 做了个均线图 http stock chenpeng info randomone 查询股票走势请移步 http stock chenpeng i
  • Java内存模型

    Android开发中 存在大量并发的情况 因此也会遇到很多线程安全问题 在查询线程安全相关资料时 通常会查到Java内存模型的知识点 Java内存模型的主要目标是定义程序中各个变量的访问规则 即在虚拟机中将变量存储到内存和从内存中取出变量这
  • 如何一次让ChatGPT输入多个版本的内容供你选择

    随着人工智能的不断进步 我们对于AI工具的需求也在日益增加 尤其是像GPT这样的高级工具 单一的答案输出已经不能满足用户的多元需求 实际上 当我们面对一个问题时 多种答案的输出能让我们更全面地了解和思考 这样我们就可以从各种可能的答案中选择
  • Nikitosh and xor【字典树+dp】

    题目链接 比较明显的 正向一个推过去的字典树 再反向退回来的一个字典树 然后异或和用差分的方式解决 字典树一定是要从第29位开始往下的 千万别从第0位往上 include
  • JavaScript常用的5种排序算法,你都掌握了吗?

    今天给大家带来5种最常见的前端排序算法 注释非常详细 欢迎讨论 1 冒泡排序 Bubble Sort 定义 冒泡排序是一种简单的比较排序算法 它重复地比较相邻的元素 并将顺序错误的相邻元素交换位置 直到整个序列排序完成 代码示例 funct
  • int 0x80系统调用的参数传递规则

    系统调用的参数传递规则 传递给系统调用的参数则必须按照参数顺序依次存放到寄存器ebx ecx edx esi edi中 当系统调用完成之后 返回值存放在eax中 A 当系统调用所需参数的个数不超过5个的时候 执行 int 0x80 指令时
  • Chroom书签同步

    Chroom自带书签管理 而且有些管理书签的插件 我感觉自带书签管理栏就能满足我的个人需求 但是有一个问题 当我换了电脑后 原来的书签怎么同步 我为什么要使用Chroom 用其他浏览器广告太多了 比如360 也试着使用国内的其他浏览器 感觉
  • 如何在vscode配置php开发环境

    3 下载并安装vscodehttps code visualstudio com 下载的是一个压缩包 将其解压至一个目录 4 在vscode中安装调试插件右侧栏中点击扩展 输入xdebug 出来的php debug 点击安装 在菜单栏 文件
  • C++ 常用容器及其使用方法

    文章目录 本章内容概述 一 Vector 1 构造函数 2 增加函数 3 删除函数 4 属性函数 二 Unordered map 1 构造函数 2 增加函数 3 删除函数 4 属性函数 三 Stack 1 构造函数 2 访问方式 3 增加函
  • python: pandas与numpy(一)创建DataFrame数组与数组的简单操作

    目录 前言 1 创建Series数组 2 创建DataFrame数组 使用字典来创建DataFrame 使用列表来创建DataFrame 使用Series数组创建DataFrame 使用numpy函数创建DataFrame 3 在DataF
  • logback.xml

  • Mayor‘s posters(线段树染色)

    题目链接 Mayor s posters 2023 4 13 更新了代码 修复了错误的离散化长度 已在代码中注出 大致题意 有n个人依次贴海报 第i个海报的范围是 li ri 后面贴的海报会覆盖掉之前贴的海报 问 最终还能看到多少张海报 解