洛谷 题解 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借教室题解
题目 这个难度感觉并没有那么高,因为这个题暴力也好打,但是比较难想出正解,因为如果你不看标签是很难想到这个题竟然是二分,当然前缀和应该很好想,毕竟让你求的是在某段时间内借教室的和是否满足. 这样我们可 ...
随机推荐
- CAS Server集成QQ登录、新浪微博登录源码及配置文件
转载自素文宅博客:https://blog.yoodb.com/yoodb/article/detail/1446 CAS Server集成QQ第三方登录,CAS Server集成新浪微博第三方登录以 ...
- nyoj 52-无聊的小明 (模拟, SET)
52-无聊的小明 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:1 submit:3 题目描述: 这天小明十分无聊,没有事做,但不甘于无 ...
- spring、mybatis、事务项目整合,附完整代码和数据库文件
配置依赖项 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...
- windows 10 上源码编译boost 1.66.0 | compile boost 1.66.0 from source on windows 10
本文首发于个人博客https://kezunlin.me/post/854071ac/,欢迎阅读! compile boost 1.66.0 from source on windows 10 Ser ...
- MAC终端中tree命令
Mac没有自带的tree命令,需要额外安装才可以,操作方法有两种: 一.用find命令模拟tree效果 1.mac下默认是没有 tree命令的,不过我们可以使用find命令模拟出tree命令的效果,如 ...
- 🔥《手把手教你》系列基础篇之3-python+ selenium-驱动浏览器和元素定位大法(详细)
1. 简介 上一篇中,只是简单地一带而过的说了一些驱动浏览器,这一篇继续说说驱动浏览器,然后再说一说元素定位的方法. 完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱 ...
- 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板
Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...
- 【2018寒假集训 Day2】【动态规划】挖地雷
挖地雷(Mine) 在一个地图上有N 个地窖(N<=200),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径,并规定路径都是单向的,且从编号小的地窖通向编号大的地窖.某人可以从任一处 ...
- 【2018寒假集训 Day1】【位运算】翻转游戏
翻转游戏(flip) [问题描述] 翻转游戏是在一个 4 格×4 格的长方形上进行的,在长方形的 16 个格上每 个格子都放着一个双面的物件.每个物件的两个面,一面是白色,另一面是黑色, 每个物件要么 ...
- day 17 re模块 正则表达式
import re 引用re模块 查找 finall:匹配所有,每一项都是列表中的一个元素 search:只匹配从左到右的第一个,得到的不是直接的结果而是一个变量,通过group方法获取结果,没 ...