洛谷 题解 P1083 【借教室】
0x00 先看数据范围
$ 1≤n,m≤10^6 $,第一反应 \(O(nlogn)\)
0x01 5 pts
直接输出 '0' 即可。
不要问我怎么知道输出 '0' 可以拿 5 pts。
保持微笑.jpeg *1
0x02 40~50 pts
考虑暴力。
按照题意枚举即可。
核心伪代码如下:
定义 n, m 为 int 型变量
定义 r 为 int 型数组,大小为 Max_N
读入 n, m
读入 r 数组
定义 d, s, t 为 int 型变量
使用变量 i 从 1 到 m 遍历
读入 d, s, t
使用变量 j 在 r 数组里从 s 到 t 遍历
r[j] 减去 d;
如果 r[j] < 0 那么
输出 "-1" 和回车
输出 i
结束程序
否则
j 指针后移
输出 "0"
结束程序
然后,考察你程序的常数的时候到了。
保持微笑.jpeg *2
0x03 70 pts
一看就是线段树。
然而,众所周知,线段树的常数是比较大的,所以只有 70 pts。
当然,我也看见了用线段树A题的大佬,在此表示由衷的敬意.
0x04 深入思考
回忆我们预测的时间复杂度:\(O(nlogn)\)
开始猜算法

——阮行止
保持微笑.jpeg *3
然后想到二分答案
0x05 二分?
设:二分答案的内容为最多可以满足第 mid 个人的需求
然后开始想 judge 函数。
这时候拼尽脑子想 \(O(n)\) 算法
然后想到差分
0x06 二分 judge 函数之差分
伪代码:
函数参数:x(int 型整数) // 表示可否满足第 x 个人的需求
Clear dif // dif 是大小为 Max_N 的 int 型数组
For i (i between [1, x])
dif[s[i]] = dif[s[i]] + d[i]
dif[t[i] + 1] = dif[t[i] + 1] - d[i]
now = 0
For i (i between [1, n])
now += dif[i];
If now > r[i] Return false;
Return true;
}
0x07 二分
int l = 0, r = m, mid;
while (l < r) {
mid = (l + r + 1) >> 1;
if (judge(mid)) l = mid;
else r = mid - 1;
}
if (l == m) putchar('0');
else puts("-1"), write(l + 1);
几点说明:
- 如果 judge(m) 为真,说明所有订单均可满足
- 因为 l 表示最多可以满足第 l 个人的需求,所以第一个需要修改订单的人的编号为 l + 1
0x08 代码
// luogu-judger-enable-o2
/**
* Problem: P1083 借教室.
* Author: 航空信奥.
* Date: 2018/08/23.
* Upload: Luogu.
*/
#include <stdio.h>
#include <string.h>
namespace HangKongXinAo {
template <typename _TpInt> inline _TpInt read();
template <typename _TpInt> inline void write(_TpInt x);
# define Max_N 1000007
int n, m, r[Max_N];
int d[Max_N], s[Max_N], t[Max_N];
int dif[Max_N];
bool judge(int x)
{
memset(dif, 0, sizeof(dif));
for (int i = 1; i <= x; i++) {
dif[s[i]] += d[i];
dif[t[i] + 1] -= d[i];
}
int now = 0;
for (int i = 1; i <= n; i++) {
now += dif[i];
if (now > r[i]) return false;
}
return true;
}
void Binary_search()
{
int l = 0, r = m, mid;
while (l < r) {
mid = (l + r + 1) >> 1;
if (judge(mid)) l = mid;
else r = mid - 1;
}
if (l == m) putchar('0');
else puts("-1"), write(l + 1);
}
int main()
{
n = read<int>();
m = read<int>();
for (int i = 1; i <= n; i++) {
r[i] = read<int>();
}
for (int i = 1; i <= m; i++) {
d[i] = read<int>();
s[i] = read<int>();
t[i] = read<int>();
}
Binary_search();
return 0;
}
char BufferRead[1 << 17];
int rLen = 0, rPos = 0;
inline char Getchar()
{
if (rPos == rLen) rPos = 0, rLen = fread(BufferRead, 1, 1 << 17, stdin);
if (rPos == rLen) return EOF;
return BufferRead[rPos++];
}
template <typename _TpInt>
inline _TpInt read()
{
register int flag = 1;
register char c = Getchar();
while ((c > '9' || c < '0') && c != '-')
c = Getchar();
if (c == '-') flag = -1, c = Getchar();
register _TpInt init = (c & 15);
while ((c = Getchar()) <= '9' && c >= '0')
init = (init << 3) + (init << 1) + (c & 15);
return init * flag;
}
template <typename _TpInt>
inline void write(_TpInt x)
{
if (x < 0) {
putchar('-');
write<_TpInt>(~x + 1);
}
else {
if (x > 9) write<_TpInt>(x / 10);
putchar(x % 10 + '0');
}
}
}
int main()
{
HangKongXinAo::main();
return 0;
}
洛谷 题解 P1083 【借教室】的更多相关文章
- 【NOIP2012】【CJOJ1093】【洛谷1083】借教室
我写的是不完美算法!!! 题面 Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的 ...
- 洛谷 1083 (NOIp2012) 借教室——标记永久化线段树 / 差分+二分
题目:https://www.luogu.org/problemnew/show/P1083 听说线段树不标记永久化会T一个点. 注意mn记录的是本层以下.带上标记的min! #include< ...
- 【题解】洛谷 P1083 借教室
目录 题目 思路 \(Code\) 题目 P1083 借教室 思路 线段树.需要的操作为区间修改,区间查询.维护每个区间的最小值就好. \(Code\) #include<iostream> ...
- 洛谷 P1083 借教室 题解
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- 洛谷P1083 借教室
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- P1083 借教室(差分+二分)
P1083 借教室 第一眼:线段树. 然鹅懒得写. 正解:差分+二分. 显然订单合法的上线可以二分 然后差分数组维护一下.没了. #include<iostream> #include&l ...
- luogu P1083 借教室 x
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- 洛谷P1083 借教室 题解
题目 [NOIP2012 提高组] 借教室 题解 这道题是几周之前做到的一道题,本来不想讲的,因为这道题也是用到了二分答案的方法,这类题目之前已经发布过两篇题解了.但这道题还运用了差分数组这个思想,所 ...
- 洛谷P1083借教室题解
题目 这个难度感觉并没有那么高,因为这个题暴力也好打,但是比较难想出正解,因为如果你不看标签是很难想到这个题竟然是二分,当然前缀和应该很好想,毕竟让你求的是在某段时间内借教室的和是否满足. 这样我们可 ...
随机推荐
- JVM原理速记复习Java虚拟机总结思维导图面试必备
良心制作,右键另存为保存 喜欢可以点个赞哦 Java虚拟机 一.运行时数据区域 线程私有 程序计数器 记录正在执行的虚拟机字节码指令的地址(如果正在执行的是Native方法则为空),是唯一一个没有规定 ...
- hdu 2647 Reward (topsort)
RewardTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Python基础教程(第3版)学习笔记
第1章.基础 1.几个小知识点 多用 help() 帮助文档 除法运算 / 除法运算,得到结果为浮点数: // 整除运算,得到整数值(向下取整): % 取余操作 (结果符号与除数符号相同),本质上: ...
- HashSet源码学习,基于HashMap实现
HashSet源码学习 一).Set集合的主要使用类 1). HashSet 基于对HashMap的封装 2). LinkedHashSet 基于对LinkedHashSet的封装 3). TreeS ...
- [Part 1] Ubuntu 16.04安装和配置QT5 | Part-1: Install and Configure Qt5 on Ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/91842b71/,欢迎阅读! Part-1: Install and Configure Qt5 on Ubuntu 16.04 ...
- python3 之 匿名函数
一.语法: lambda 参数:方法(或三元运算) #最多支持3元运算 二.实例1:基础 #函数1: a = lambda x:x*x print(a(2)) #函数2: def myfun(x): ...
- Linux下为知笔记和蚂蚁笔记测评,推荐蚂蚁笔记!(非广告)
本人由于学习Linux,需要一款可以在Linux平台下可以运行的一款软件,了解到为知笔记之笔记(下文以W代替)和蚂蚁笔记(下文以M代替)比较出名,由于某云和某象笔记在linux平台下没有对应的软件,所 ...
- linux计算机网络基础
OSI7层协议和TCP/IP4层网络协议 第一层:物理层,定义各种物理设备的规范,如通信距离,接口大小等. 第二层:数据链路层,基于mac地址通信是,数据报文封装和相应方式. 第三层:网络层,基于IP ...
- vue 做一个简单的TodoList
目录结构 index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...
- Android Studio 2.2 NDK开发环境搭建
转载请标明出处:http://blog.csdn.net/shensky711/article/details/52763192 本文出自: [HansChen的博客] Android应用程序使用ND ...