E1. Canteen (Easy Version)E2 Canteen (Hard Version) 对于旋转操作的深入理解

news/2025/3/28 16:24:14/文章来源:https://www.cnblogs.com/archer233/p/18790498

E1. Canteen (Easy Version) 题解:二分查找 + 模拟

本文大量学习了jiangly的代码对其进行详细的解析并作图对其进行解释

题目链接

深入解析:前缀和最小值旋转的直观意义


一、前缀和曲线的数学本质

我们定义前缀和数组为:

pre[i+1] = pre[i] + a[i] - b[i]

这一公式的物理意义是:从起点到位置 i 的累积过程中,a 的总和比 b 少多少(若为负值,则说明 b 的总和超过 a)。
例如,假设 a = [1, 2, 3]b = [4, 1, 4],则前缀和为:

pre = [0, 0+1-4=-3, -3+2-1=-2, -2+3-4=-3]

此时 pre[1]=-3 是前缀和的最小值。


二、为何旋转到最小值位置?

通过循环左移,将前缀和的最小值位置 x 设为新起点,本质是b 的累积优势最大化区间对齐到数组开头
以下通过图像化示例说明:

1. 前缀和曲线示意图

假设前缀和曲线形状如下(横轴为索引,纵轴为 pre[i]):

pre: 0 → -3 → -5 → -2 → 0  (最小值在索引2)
  • 负值区域:表示 b 的累积优势区(b 总和显著超过 a)。
  • 正值区域:表示 a 的累积过剩区(需后续处理)。
2. 旋转后的效果

将最小值位置 x=2 设为新起点,前缀和曲线变为:

新 pre: -5 → -2 → 0 → -3 → 0

此时,曲线从最小值开始逐步上升,后续的 b 元素(如索引3的 b[3]=4)可以更高效地处理积压的 a 元素。


三、栈模拟与贪心抵消的直观演示

1. 栈的作用

栈中存储的是未被抵消的 a 元素的索引。例如:

  • 初始时 a = [3,4,1,2]b = [2,1,4,3](旋转后)。
  • 处理 b[2]=4 时,栈顶的 a[0]=3a[1]=4 可被快速抵消。
2. 时间窗口限制

假设允许轮数 mid=2

  • 若当前处理到 i=2,栈顶元素 j=0,则 i-j=2 满足条件。
  • b[2]=4 可抵消 a[0]a[1],无需计入 k 操作。

四、为何“正值累加不超过最小负值差”?

  1. 数学原理
    前缀和的最小值为 pre_min,最终 pre[n]=0(因 sum(a) ≤ sum(b))。
    pre_minpre[n] 的累加为 -pre_min,即所有正值区域的累加不超过 -pre_min
    物理意义b 的累积优势足以覆盖所有 a 的过剩部分。

  2. 图像验证
    从前缀和最小值开始,曲线逐步上升至终点。上升部分的累加值(正值区域)必然被初始的负值深度(pre_min)所限制。


五、动手画图理解

  1. 步骤示例

    • 画横轴为索引,纵轴为 pre[i]
    • 标记最小值点 x,旋转后曲线从 x 开始。
    • 观察旋转后的曲线是否满足“上升段总和 ≤ |pre_min|”。
  2. 实例验证
    以样例输入中的第六个测试用例为例:

    a = [1,2,3,4], b = [4,3,2,1]
    pre = [0, -3, -4, -3, 0]
    

    旋转到 x=2 后,ab 变为:

    a = [3,4,1,2], b = [2,1,4,3]
    

    此时 b[2]=4b[3]=3 能高效处理栈中积压的 a 元素,减少轮数。


#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int mod=998244353;
int gcd(int a,int b){return b?gcd(b,a%b):a;};
int qpw(int a,int b){int ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
int inv(int x){return qpw(x,mod-2);}
void solve(){int n,k; cin>>n>>k;vector<int>a(n),b(n);for (int i=0;i<n;i++)cin>>a[i];for (int i=0;i<n;i++)cin>>b[i];vector<int>pre(n+1);for (int i=0;i<n;i++) {pre[i+1]=pre[i]+a[i]-b[i];//因为题目中指出sum(b)>=sum(a)所以我们需要计算这个b的前缀-a的前缀的最大点 将其作为旋转使其可以实现完全匹配}// 可能有同学会不太理解为什么把b前缀减去a前缀的最大移动到最后就一定能够实现完全匹配 因为我们要实现一个类似于栈的移动匹配// 我们把优先b能够实现匹配的数放到前面这样栈里面就能够存储未实现匹配的a// 把匹配的压力优先放到后面 访问到后面的b时能够最大限度地对前面地a进行删除// 如果还是太过抽象 那么我们可以将其想象成一边是单调下降一边是单调上升的曲线// 对于曲线上升为正数的部分我们会进行保留即为被保存在栈中 为负数的部分我们会忽略// 那么见图可以得知该结论是正确的 具体原理为直线的正值累加是不可能超过最小负值点的差// 您也可以自己画着试试{int x=ranges::min_element(pre)-pre.begin();rotate(a.begin(),a.begin()+x,a.end());rotate(b.begin(),b.begin()+x,b.end());}vector<int>na,nb;auto check=[&](int x) {na=a,nb=b;int sum=0;stack<int>stk;for (int i=0;i<n;i++) {stk.push(i);while (!stk.empty()&&nb[i]>0) {int j=stk.top();if (i-j>=x) {sum+=na[j];stk.pop();}else {int t=min(na[j],nb[i]);na[j]-=t;nb[i]-=t;if (na[j]==0) {stk.pop();}}}}return sum<=k;};int l=0,r=n;int ans=0;while (l<=r) {int mid=(l+r)>>1;if (check(mid)) {ans=mid;r=mid-1;}else l=mid+1;}cout<<ans<<endl;
}
signed main(){ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);int _=1;cin>>_;while(_--)solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/905096.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20244209 2024-2025-2 《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…

ASP.NET Core WebApi+React UI开发入门详解

在前段时间,有粉丝反馈能否写一篇基于ASP.NET Core Web Api+React UI进行Web开发的文章,经过查阅相关资料,发现Visual Studio 2022已经集成相关模板,可以在Visual Studio中直接创建项目项目,今天以一个小例子,简述ASP.NET Core Web Api+React UI开发系统的基本步骤,仅供…

一文速通Python并行计算:02 Python多线程编程-threading模块、线程的创建和查询与守护线程

本文介绍了Python threading模块的核心功能,包括线程创建与管理、线程状态监控以及守护线程的特殊应用,重点讲解了Thread类的实例化方法、获取当前线程信息、检测线程存活状态,以及如何实现后台线程。一文速通 Python 并行计算:02 Python 多线程编程-threading 模块、线程的…

编程神器Trae:当我用上后,才知道自己的创造力被低估了多少

"AI会让每个人都能成为工具创造者,打破你能力边界,有时候只需要一个想法。" AI粉嫩特攻队,2025年3月23日。 前几天参加了一场行业闭门研讨会,满满1个半小时的干货演讲让我收获颇丰。会后,我迫不及待地想将录音整理成文字,方便日后回顾。却被提示"文件过大…

20244212喻浩川《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名: 喻浩川 学号:20244212 实验教师:王志强 实验日期:2025年3月25日 必修/选修: 公选课 1.实验内容 (1)熟悉Python开发环境; (2)练习Python运行、调试技能; (3)编写程序,练习变量和类型、字符串、对象、缩进和注释等; (4)编写…

龙哥量化:deepseek写公式是需要思路的, 我整理的公式思路,请点赞收藏, 我持续更新ing

龙哥微信:Long622889代写技术指标_选股公式: 通达信,同花顺,东方财富,大智慧,文华,博易,飞狐代写量化策略: TB交易开拓者,文华8,金字塔AI写代码,很多朋友都试过了 deepseek,腾讯元宝,通义千问,豆包,chatgpt,通达信内嵌AI写公式,同花顺内嵌AI写公式,等等,写…

SciTech-EECS-Circuits-电路稳定性: 温度补偿 的几种方式对比: 响应时问、精度、动态范围、线性度、稳定度

电路稳定性: 温度稳定性 测试的几种方式:电吹风加热 冰箱(-5度) + 烤箱(50度/70度)改进 "文氏电桥振荡" 电路 的“热稳定性温度补偿” 网上找来找去,都是用FET(场效应管)做成"压控电阻"控制 "振荡器"的"增益",达到稳幅的目的。 但电…

SpringBoot3+Vue3实现查询功能

安装axios封装前后端对接数据工具npm i axios -S通过requst.js工具类发起请求import axios from "axios"; import {ElMessage} from "element-plus";const request = axios.create({baseURL:http://localhost:8080,//后端统一的请求地址timeout:30000 //后…

Apache Echarts 入门学习 -2025/3/24

介绍 一种数据可视化技术echats官方文档: https://echarts.apache.org/handbook/zh/get-started/ <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>第一个 ECharts 实例</title><!-- 引入 echarts.js --><…

[数据资产/数据标准/行标] 电力数据交易分类分级管理规范(团体标准)

发布单位: 广东省网络空间安全协会附录A (资料性) 数据分类示例附录B (资料性) 数据分级示例附录C (规范性) 数据分级安全保护要求X 参考文献【团标】电力数据交易分类分级管理规范 - Weixin/数据工匠俱乐部本文作者:千千寰宇本文链接:https://www.cnblogs.com/johnnyzen关于…

Netty源码—5.Pipeline和Handler

大纲 1.Pipeline和Handler的作用和构成 2.ChannelHandler的分类 3.几个特殊的ChannelHandler 4.ChannelHandler的生命周期 5.ChannelPipeline的事件处理 6.关于ChannelPipeline的问题整理 7.ChannelPipeline主要包括三部分内容 8.ChannelPipeline的初始化 9.ChannelPipeline添加…

A important person

When I saw this title,the first “person” that came to mind was my little sister, my puppy dog called LaiBao. I still remember the first day I saw her. My mom bought it on internet and the solder took her to us. She was too small at that time. She curled…