洛谷 题解 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借教室题解
题目 这个难度感觉并没有那么高,因为这个题暴力也好打,但是比较难想出正解,因为如果你不看标签是很难想到这个题竟然是二分,当然前缀和应该很好想,毕竟让你求的是在某段时间内借教室的和是否满足. 这样我们可 ...
随机推荐
- Jenkins + docker ,容器中跑docker服务
1. 宿主机:安装docker 2. 启动jenkins服务 https://jenkins.io/download/ Jenkins官网找自己需要的镜像版本号进行使用. docker run -it ...
- C# VI: 删除字符串中指定字符的几种方法
本文基于Stackoverflows上以下几个Question: Fastest way to remove chars from string (http://stackoverflow.com/q ...
- Bootstrap——面包屑导航(Breadcrumbs)
面包屑导航(Breadcrumbs)是一种基于网站层次信息的显示方式. Bootstrap 中的面包屑导航(Breadcrumbs)是一个简单的带有 .breadcrumb 类的无序列表. <o ...
- 领扣(LeetCode)二叉树的中序遍历 个人题解
给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 递归的思路很简单,不再累 ...
- Linux下使用Nginx做CDN服务器下的配置
由于使用docker配置Nginx比较方便,所以博主就使用docker做为容器配置下 第一步.配置docker-compose.yml文件 version: services: nginx: rest ...
- java学生管理系统
student类 package cn.itheima.Manag; /** * *标准类 * **/public class Student { //学号 private String id; // ...
- sublime插件开发教程2
直接进入正题 先新建个chajian.py python写起 import sublime import sublime_plugin class ExampleCommand(sublime_plu ...
- JDK1.8新特性(一):stream
一.什么是stream? 1.概述 Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据. 这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管 ...
- Sublime Text最好的中文教程
原文链接:http://lucida.me/blog/sublime-text-complete-guide/ 摘要(Abstract) 本文系统全面的介绍了Sublime Text,旨在成为最优秀的 ...
- Select2 禁用option
禁用 $("#priceGroupType option[value='1']").prop('disabled', true); $("#priceGroupType& ...