洛谷 P11830 省选联考2025 幸运数字 题解
题意
小 X 有 n n n 个正整数二元组 ( a i , b i ) ( 1 ≤ i ≤ n ) (a_i, b_i) (1 \leq i \leq n) (ai,bi)(1≤i≤n)。他将会维护初始为空的可重集 S S S,并对其进行 n n n 轮操作。第 i ( 1 ≤ i ≤ n ) i (1 \leq i \leq n) i(1≤i≤n) 轮操作中,他会在 S S S 中加入 a i a_i ai 个 b i b_i bi。
设 m = ∑ i = 1 n a i m = \sum \limits_{i=1}^{n} a_i m=i=1∑nai,在所有操作结束后,小 X 会得到一个包含 m m m 个正整数的可重集 S S S。最后他会计算 S S S 的中位数,即 S S S 中第 ⌊ m + 1 2 ⌋ \left\lfloor \frac{m+1}{2} \right\rfloor ⌊2m+1⌋ 小的数,作为他的幸运数字。
想知道小 X 幸运数字的小 Y 不知道这 n n n 个二元组的具体数值是多少,但她得知了每个数的范围。具体地,对于每个 1 ≤ i ≤ n 1 \leq i \leq n 1≤i≤n,小 Y 知道 a i ∈ [ l i , 1 , r i , 1 ] a_i \in [l_{i,1}, r_{i,1}] ai∈[li,1,ri,1] 且 b i ∈ [ l i , 2 , r i , 2 ] b_i \in [l_{i,2}, r_{i,2}] bi∈[li,2,ri,2]。
小 Y 想知道在满足以上条件的情况下,有多少个数可能成为小 X 的幸运数字。
设 ∑ n \sum n ∑n 为单个测试点内所有测试数据的 n n n 的和。对于所有测试点:
- 1 ≤ T ≤ 400 1 \leq T \leq 400 1≤T≤400
- 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1≤n≤2×105, 1 ≤ ∑ n ≤ 6 × 1 0 5 1 \leq \sum n \leq 6 \times 10^5 1≤∑n≤6×105
- ∀ 1 ≤ i ≤ n \forall 1 \leq i \leq n ∀1≤i≤n, 1 ≤ l i , 1 ≤ r i , 1 ≤ 1 0 9 1 \leq l_{i,1} \leq r_{i,1} \leq 10^9 1≤li,1≤ri,1≤109, 1 ≤ l i , 2 ≤ r i , 2 ≤ 1 0 9 1 \leq l_{i,2} \leq r_{i,2} \leq 10^9 1≤li,2≤ri,2≤109。
思路
假如有一个数列,一个值 m m m 的个数为 b b b,比它小的数的个数为 a a a,比它大的数的个数为 c c c,对于中间位置 m i d = ⌊ a + b + c + 1 2 ⌋ mid=\left \lfloor \frac{a+b+c+1}{2} \right \rfloor mid=⌊2a+b+c+1⌋:
- m i d ≤ a mid\le a mid≤a,那么中间位置在小于 m m m 的数中,中位数小于 m m m;
- a < m i d ≤ a + b a<mid\le a+b a<mid≤a+b,那么中间位置在一堆 m m m 中,中位数就是 m m m;
- m i d > a + b mid>a+b mid>a+b,那么中间位置在大于 m m m 的数中,中位数大于 m m m。
那么,当我们知道 m m m 的个数、小于和大于 m m m 的数的个数,就可以知道 m m m 是否为中位数。将这样的操作集成为函数 M i d ( a , b , c ) \rm {Mid}(a,b,c) Mid(a,b,c),三种类型分别为 − 1 , 0 , 1 -1,0,1 −1,0,1。
但是题目中给的是个数的区间,那要怎么办呢?
考虑从题目给的“个数区间”下手,如果可以维护两对区间:小于 m m m 的数的个数区间为 [ l l e s , r l e s ] [l_{les},r_{les}] [lles,rles],大于 m m m 的数的个数区间为 [ l b i g , r b i g ] [l_{big},r_{big}] [lbig,rbig]。如果存在 Mid ( r l e s , c n t m , l b i g ) = 0 \textup{Mid}(r_{les},cnt_m,l_{big})=0 Mid(rles,cntm,lbig)=0 或者 Mid ( l l e s , c n t m , r b i g ) \textup{Mid}(l_{les},cnt_m,r_{big}) Mid(lles,cntm,rbig),显然 m m m 为中位数。
还有两种情况就是,小于 m m m 的数的个数取得少、大于 m m m 的数的个数取得多,或者小于 m m m 的数的个数取得多、大于 m m m 的数的个数取得少。这两种情况的可行性体现于:
Mid ( r l e s , c n t m , l b i g ) ≠ Mid ( l l e s , c n t m , r b i g ) \textup{Mid}(r_{les},cnt_m,l_{big})\neq\textup{Mid}(l_{les},cnt_m,r_{big}) Mid(rles,cntm,lbig)=Mid(lles,cntm,rbig)
(感性理解就是)因为两端个数 a ∈ [ l l e s , r l e s ] a\in [l_{les},r_{les}] a∈[lles,rles]、 c ∈ [ l b i g , r b i g ] c\in[l_{big},r_{big}] c∈[lbig,rbig], a a a 和 c c c 可以取各自区间的任意一个数;而“不等于”相当于存在 r l e s > l b i g , l l e s < r b i g r_{les}>l_{big},l_{les}<r_{big} rles>lbig,lles<rbig 或者 r l e s < l b i g , l l e s > r b i g r_{les}<l_{big},l_{les}>r_{big} rles<lbig,lles>rbig,可以构造出 m m m 是中位数的情况。
ll Mid(ll a,ll b,ll c)
{ll mid=(a+b+c+1)>>1;if(a>=mid)return -1;if(a+b>=mid)return 0;return 1;
}
bool MID(ll m)
{ll c1=Mid(les.r,m,big.l),c2=Mid(les.l,m,big.r);return m&&(!c1||!c2||c1!=c2);
}
那只要能维护出上文的两对区间就可以了。
因为只求个数,不需要知道具体哪一个,而且注意到题目给的 l i , 1 , r i , 1 , l i , 2 , r i , 2 l_{i,1},r_{i,1},l_{i,2},r_{i,2} li,1,ri,1,li,2,ri,2 较大,考虑离散化。然后套路地用两个动态数组分别季度左右端点的信息,以便进行枚举过程中的信息修改。
枚举一堆 m m m 是否为中位数时,贪心地取 m m m 的最多数量(比较明显的贪心)。
先初始化 l e s les les 和 b i g big big 区间,然后直接在离散化的下标哪里扫过去:在 m m m 和 m + 1 m+1 m+1 的转移中,使用先前维护的动态数组,分别加入和删除当前中位数和不符合条件的中位数的信息:从 b i g big big 区间删去当前中位数的信息,在 l e s les les 区间中加入被弹出的数的信息。
答案就是相邻区间个数和。使用离散后的数组就可以计算。
一些细节和写法见代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e6+9,inf=0x7f7f7f7f;
int id,T,n;
struct term
{ll l,r;
}a[N],b[N],les,big;
ll bb[N];
ll Mid(ll a,ll b,ll c)
{ll mid=(a+b+c+1)>>1;if(a>=mid)return -1;if(a+b>=mid)return 0;return 1;
}
bool MID(ll m)
{ll c1=Mid(les.r,m,big.l),c2=Mid(les.l,m,big.r);return m&&(!c1||!c2||c1!=c2);
}
vector<term>s[N],t[N];
void clean(ll nn)
{for(int i=1;i<=nn;i++)s[i].clear(),t[i].clear();
}
int main()
{scanf("%d%d",&id,&T);while(T--){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lld%lld%lld%lld",&a[i].l,&a[i].r,&b[i].l,&b[i].r);bb[i*2-1]=b[i].l;bb[i*2]=b[i].r+1;}sort(bb+1,bb+2*n+1);ll nn=unique(bb+1,bb+2*n+1)-bb-1;les.l=les.r=big.l=big.r=0;//在中位数枚举的转移中,动态维护两对区间//比中位数大/小的个数区间 //[les.l,les.r] cntmid [big.l,big.r]for(int i=1;i<=n;i++){b[i].l=lower_bound(bb+1,bb+nn+1,b[i].l)-bb;//离散化b[i].r=lower_bound(bb+1,bb+nn+1,b[i].r+1)-bb;// cout<<b[i].l<<" "<<b[i].r<<endl;s[b[i].l].push_back(a[i]);//套路地,只记录左右端点信息t[b[i].r].push_back(a[i]);big.l+=a[i].l,big.r+=a[i].r;//big区间初始化}ll cntmid=0,ret=0;for(int i=1;i<=nn;i++){for(auto x:s[i]){cntmid+=x.r;//加入中位数,贪心的取数量更多的中位数 big.l-=x.l,big.r-=x.r;//从big区间删去}for(auto x:t[i]){cntmid-=x.r;//弹出不符合条件的 les.l+=x.l,les.r+=x.r;//弹出的加入les区间 }// cout<<les.l<<" "<<les.r<<" "<<big.l<<" "<<big.r<<endl;if(MID(cntmid))ret+=bb[i+1]-bb[i];//这段区间都能是中位数,统计个数}printf("%lld\n",ret);clean(nn);}return 0;
}
相关文章:
洛谷 P11830 省选联考2025 幸运数字 题解
题意 小 X 有 n n n 个正整数二元组 ( a i , b i ) ( 1 ≤ i ≤ n ) (a_i, b_i) (1 \leq i \leq n) (ai,bi)(1≤i≤n)。他将会维护初始为空的可重集 S S S,并对其进行 n n n 轮操作。第 i ( 1 ≤ i ≤ n ) i (1 \leq i \leq n) i(1≤i≤n) 轮操作中&#…...
win11编译pytorchaudio cuda128版本流程
1. 前置条件 本篇续接自 win11编译pytorch cuda128版本流程,阅读前请先参考上一篇配置环境。 访问https://kkgithub.com/pytorch/audio/archive/refs/tags/v2.6.0.tar.gz下载源码,下载后解压; 2. 编译 在visual studio 2022安装目录下查找…...
JAVA面经2
ConcurrentHashMap 并发程序出现问题的根本原因 线程池 线程池的执行原理(核心参数) 线程池的常见阻塞队列 ArrayBlockingQueue插入和删除数据,只采用了一个lock,而LinkedBlockingQueue则是在插入和删除分别采用了putLock和takeL…...
NLP学习记录十一:位置编码
目录 一、位置编码的意义 二、位置编码方法 三、代码实现 一、位置编码的意义 在标准的注意力机制中,每个查询都会关注所有的键-值对并生成一个注意力输出,模型并没有考虑到输入序列每个token的顺序关系。 以["我&qu…...
CF 886A.ACM ICPC(Java实现)
题目分析 输入6个值,判断某三个值的和能够等于另外三个值的和 思路分析 首先判断总和是不是一个偶数,如果不是就“NO”。由于小何同学算法不好,只能使用三层for循环强行判断某三个值是否能等于总和的一半,可以就“YES”。 代码 …...
【音视频】H265解码Nalu后封装rtp包
概述 基于ZLM流媒体框架以及简单RTSP服务器开源项目分析总结,相关源码参考以下链接 H265-rtp提取Nalu逻辑 通过rtsp流地址我们可以获取视频流中的多个rtp包,其中每个RTP包中又会包含一个或者多个Nalu,将其提取处理 总体逻辑分析 核心逻辑在…...
Linux -- I/O接口,文件标识符fd、file结构体、缓冲区、重定向、简单封装C文件接口
一、理解文件 狭隘理解(传统视角) 聚焦物理存储:文件特指存储在磁盘等外存设备上的二进制数据集合输入输出特性: 写入文件:CPU 通过总线将数据输出到磁盘读取文件:磁盘通过 DMA 将数据输入到内存 ÿ…...
系统讨论Qt的并发编程2——介绍一下Qt并发的一些常用的东西
目录 QThreadPool与QRunnable 互斥机制:QMutex, QMutexLocker, QSemaphore, QWaitCondition 跨线程的通信 入门QtConcurrent,Qt集成的一个并发框架 一些参考 QThreadPool与QRunnable QThreadPool自身预备了一些QThread。这样,我们就不需…...
【数据挖掘】Pandas之DataFrame
在 Pandas 中,DataFrame 提供了丰富的数据操作功能,包括 查询、编辑、分类和汇总。 1. 数据查询(Filtering & Querying) 1.1 按索引或列名查询 import pandas as pddata {"ID": [101, 102, 103, 104, 105],"…...
C++:volatile、const、mutable关键字
文章目录 volatile、const、mutable 关键字的作用、联系与区别 1️⃣ **volatile** —— 防止编译器优化,确保变量每次访问都从内存读取**作用****使用场景****示例** 2️⃣ **const** —— 限制变量的修改,保证不可变性**作用****使用场景****示例** 3️…...
linux离线安装miniconda环境
1 下载安装包 可以在官网下载最新版 https://www.anaconda.com/download/success#miniconda 或者在软件目录选择合适的版本 https://repo.anaconda.com/miniconda/ 安装包传入离线服务器 ./Miniconda3-py311_24.9.2-0-Linux-x86_64.sh2 运行安装包 ./Miniconda3-py311_24…...
考研408数据结构线性表核心知识点与易错点详解(附真题示例与避坑指南)
一、线性表基础概念 1.1 定义与分类 定义:线性表是由n(n≥0)个相同类型数据元素构成的有限序列,元素间呈线性关系。 分类: 顺序表:元素按逻辑顺序存储在一段连续的物理空间中(数组实现&…...
selenium用例执行过程采集操作形成测试报告上的回复
在代码执行的过程中不断的进行截图,把截图拼接成gif动态图,放在测试报告上 1、每条用例执行启动一个线程,这个线程会每隔0.3秒进行截图 项目下创建一个临时目录video用来存储所有截图以及gif动态图封装不断截图的方法,每隔0.3秒…...
多元数据直观表示(R语言)
一、实验目的: 通过上机试验,掌握R语言实施数据预处理及简单统计分析中的一些基本运算技巧与分析方法,进一步加深对R语言简单统计分析与图形展示的理解。 数据: 链接: https://pan.baidu.com/s/1kMdUWXuGCfZC06lklO5iXA 提取码: …...
【JavaEE】线程安全
【JavaEE】线程安全 一、引出线程安全二、引发线程安全的原因三、解决线程安全问题3.1 synchronized关键字(解决修改操作不是原子的)3.1.1 synchronized的特性3.1.1 synchronized的使用事例 3.2 volatile 关键字(解决内存可见性) …...
HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法
【高心星出品】 文章目录 多线程Worker和Sendable的使用方法开发步骤运行结果 多线程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一种多线程的实现方式,它允许开发者在后台线程中执行长耗时任务,从而避免阻塞主线程并提高应用的响应性。 S…...
华为OD-2024年E卷-分批萨[100分]
文章目录 题目描述输入描述输出描述用例1解题思路Python3源码 题目描述 吃货"和"馋嘴"两人到披萨店点了一份铁盘(圆形)披萨,并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。但是粗心的服务员将披萨切成了每块大小都完全不…...
SSH监控
创建/etc/ssh/sshrc文件 写入以命令 echo " 系统状态 " uptime free -h 每次登录会显示 如果在sshrc文件加入以下脚本每次登录就是执行这个脚本 # cat /etc/ssh/sshrc echo " 系统状态 " uptime free -h /usr/local/bin/monit.sh以…...
leetcode日记(74)扰乱字符串
很有难度的一题,一开始真的绕了很多思维上的弯路。 最开始的想法是递归,看到题目的时候想到动态规划但是完全没有思路应该怎么用,结果确实是递归动态规划。 最开始的想法是构建树,每一层包含这一步划分的方法(实际会…...
RV1126的OSD模块和SDL_TTF结合输出H264文件
目录 一.RV1126多线程处理输出OSD字符叠加图层的流程 1.1. VI模块的初始化 1.2. 初始化VENC模块: 1.3. 初始化RGN模块: 1.4. 绑定VI模块和VENC模块,伪代码如下 1.5. 创建多线程进行OSD字库的叠加: 1.6. 获取每一帧处理过后的…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
