洛谷P1083借教室题解
这个难度感觉并没有那么高,因为这个题暴力也好打,但是比较难想出正解,因为如果你不看标签是很难想到这个题竟然是二分,当然前缀和应该很好想,毕竟让你求的是在某段时间内借教室的和是否满足。
这样我们可以很容易的推出借的教室的个数和订单是成正对应的,因此他可以满足单调性,所以我们就可以用上二分。
而原题中我们可以把天数看成x轴上的横坐标,这天的借教室数可以看成y轴上的纵坐标,而每一次订单的增加,我们就要让从第一个订单到这个订单中的所有订单都加起来,这就像一个区间修改,然后我们在判断的时候就需要用到单点查询这天满不满足。
因此我们可以想到差分数组和前缀和的结合,然后再搭配二分,就ok了。
代码:
// luogu-judger-enable-o2 #include<iostream> #include<cstring> #include<cstdio> #define M 1000010 using namespace std; struct cym { int l ,r, d; } e[M]; int delta[M], sum[M], nul[M], n, m; bool flag; bool check(int x) { memset(delta, 0, sizeof(delta)); for(int i = 1; i <= x; i++) { delta[e[i].l] += e[i].d; delta[e[i].r + 1] -= e[i].d; } for(int i = 1; i <= n; i++) { sum[i] = sum[i - 1] + delta[i]; if(sum[i] > nul[i]) return false; } return true; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf ("%d", &nul[i]); for (int i = 1; i <= m; i++) scanf ("%d%d%d", &e[i].d, &e[i].l, &e[i].r); for(int i = 1; i <= m; i++) { delta[e[i].l] += e[i].d; delta[e[i].r + 1] -= e[i].d; } for(int i = 1; i <= n; i++) { sum[i] = sum[i - 1] + delta[i]; if(sum[i] > nul[i]) flag = 1; } if(!flag) { printf("0"); return 0; } int left = 1, right = m; while (left < right) { int mid = (left+right) / 2; if (check(mid)) left = mid + 1; else right = mid; } printf ("-1\n%d", left); }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· dotnet 源代码生成器分析器入门
· Draw.io:你可能不知道的「白嫖级」图表绘制神器
· ASP.NET Core 模型验证消息的本地化新姿势
· 从零开始:基于 PyTorch 的图像分类模型
· [WPF] 在RichTextBox中输出Microsoft.Extension.Logging库的