洛谷 题解 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借教室题解
题目 这个难度感觉并没有那么高,因为这个题暴力也好打,但是比较难想出正解,因为如果你不看标签是很难想到这个题竟然是二分,当然前缀和应该很好想,毕竟让你求的是在某段时间内借教室的和是否满足. 这样我们可 ...
随机推荐
- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 - 推酷 - 360安全浏览器 7.1
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring - 大新博客 时间 2014-02-11 21:08:00 博客园-所有随笔区 ...
- VsCode Python配置安装教程
1.软件下载地址 Python官网: https://www.python.org/downloads/windows/ Python下载地址: https://www.python.org/ftp/ ...
- 高性能Web动画和渲染原理系列(5)合成层的生成条件和陷阱
目录 一. 硬件加速相关的几个概念 二. 合成层的生成条件 显式提升 隐式提升 三. 硬件加速的权衡 四. 动画实现的一些建议 示例代码托管在:http://www.github.com/dashno ...
- canvas入门,就是这个feel!
钙素 Canvas 是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图.也就是说我们将通过JS完成画图而不是css. canva ...
- 18063-圈中的游戏-(第九章第4题)-"数组指针的使用"-数学分析
代码借鉴CSDN大佬https://blog.csdn.net/weixin_41409140/article/details/88071047(对大佬的大佬代码进行分析) 18063 圈中的游戏 时 ...
- ArcGIS 发布Feature服务
运行环境: Win10 ArcGIS10.4 具体操作: 1.打开ArcMap,加载sde中导入的文件,也可以加载shp数据源指向sde中文件 2.保存成mxd,然后点share as-Service ...
- vue 中 keep-alive 缓存数据、离开时位置
路由中: 页面中: 需要缓存的组件中: 因为是keep-alive 所以在初始化页面的时候 会走一次生命周期 当二次进入的时候就已经是缓存状态了 不会在走生命周期 于是它就有了自己的周期函数分别是 ...
- Oracle 分区表管理之组合分区(分区索引失效与性能比较)
整体结构如下: Oracle 分区表管理之组合分区(分区索引失效与性能比较) 虽然老早就使用了分区表,终于有时间写有关分区表的内容:不是所有的场景数据量变大需要用到分区表,一般单表数据超过2g可以考 ...
- postgresql修改最大连接数配置
1.查看配置文件位置等信息,用来确定配置对应的配置文件. select setting,boot_val,reset_val,sourcefile,*from pg_settings where n ...
- Spring(Bean)6
生命周期构造 --->set--->Bean init前后执行 (新创建 类) public class MyBeanPostProcesser implements BeanPostPr ...