当前位置: 首页 > news >正文

codeforces 2057D. Gifts Order

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目大意

给定一个长度为n数组 an

设l~r的最大价值为
m a x ( a l , a l + 1 , . . . , a r ) − m i n ( a l , a l + 1 , . . . , a r ) − ( r − l ) max(a_l,a_{l+1},...,ar)-min(a_l,a_{l+1},...,ar)-(r-l) max(al,al+1,...,ar)min(al,al+1,...,ar)(rl)

共有两种操作,一是给你位置p和值x,修改第p个位置的值为x
第二是an数组中选择一个l,r,使得l~r为数组的最大价值

思路

分析一下,当最大值在左边,最小值在右边时,式子可变为 ( a l + l ) − ( a r + r ) (a_l+l)-(a_r+r) (al+l)(ar+r),相反则为 ( a r − r ) − ( a l − l ) (a_r-r)-(a_l-l) (arr)(all)
所以针对两种情况我们可以化简为 a i + i a_i+i ai+i a i − i a_i-i aii
维护每个区间的两种情况的最大值最小值
区间(1~n)查询和单点修改,可以用线段树来解决,
设数组tr,第一维度 0 代表 a l > a r , 1 代表 a l < = a r 0代表al>ar,1代表al<=ar 0代表al>ar,1代表al<=ar
第二维0代表区间最小值,1代表区间最大值,val数组代表当前节点的最大价值
在pushup操作求节点最大值时,可以是两个子节点的最大值,也可以是以下两种情况
a l > a r a_l>a_r al>ar时(ai+i),即最大值在左边,最小值在右边,那么就用左边的最大值减去左边的最小值
a l < = a r a_l<=a_r al<=ar时(ai-i),即最大值在右边,最小值在左边的情况,就用右边的最大值减去左边的最小值

// Author: zengyz
// 2025-06-12 18:15#include <bits/stdc++.h>using namespace std;
using i64 = long long;
const int N = 2e5 + 10;
int tr[2][2][N * 4], val[N * 4];
int a[N];
void pushup(int u)
{tr[0][0][u] = min(tr[0][0][u << 1], tr[0][0][u << 1 | 1]);tr[0][1][u] = max(tr[0][1][u << 1], tr[0][1][u << 1 | 1]);tr[1][0][u] = min(tr[1][0][u << 1], tr[1][0][u << 1 | 1]);tr[1][1][u] = max(tr[1][1][u << 1], tr[1][1][u << 1 | 1]);val[u] = max(tr[0][1][u << 1] - tr[0][0][u << 1 | 1], tr[1][1][u << 1 | 1] - tr[1][0][u << 1]);val[u] = max(val[u], max(val[u << 1], val[u << 1 | 1]));
}
void build(int u, int l, int r)
{if (l == r){tr[0][0][u] = tr[0][1][u] = a[l] + l;tr[1][0][u] = tr[1][1][u] = a[l] - l;val[u] = 0;return;}else{int mid = (l + r) >> 1;build(u << 1, l, mid);build(u << 1 | 1, mid + 1, r);pushup(u);}
}
void modify(int u, int l, int r, int p, int x)
{if (l == r){tr[0][0][u] = tr[0][1][u] = x + p;tr[1][0][u] = tr[1][1][u] = x - p;return;}int mid = (l + r) >> 1;if (p <= mid)modify(u << 1, l, mid, p, x);elsemodify(u << 1 | 1, mid + 1, r, p, x);pushup(u);
}void solve()
{int n, q;cin >> n >> q;for (int i = 1; i <= n; i++)cin >> a[i];build(1, 1, n);cout << val[1] << endl;while (q--){int p, x;cin >> p >> x;a[p] = x;modify(1, 1, n, p, x);cout << val[1] << endl;}return;
}int main()
{ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int _T = 1;cin >> _T;while (_T--){solve();}return 0;
}
http://www.xdnf.cn/news/1011151.html

相关文章:

  • 动态规划2——路径动态规划
  • [MSPM0开发]MSPM0G3507之GPIO输入、输出、中断使用(基于driverlib库)
  • firebase异常捕获
  • ssc377d系统裁剪(16M nor flash)
  • 非标定制超声波清洗设备的核心技术解析与应用
  • RAID 阵列有哪些?分别有什么作用?
  • 【读代码】RAG文档解析工具Marker
  • 日语单词总结
  • Flink 系列之二十九- Flink SQL - 中间算子:窗口聚合
  • Ubuntu安装RTX5090显卡驱动
  • Java开发中常见的语法陷阱与规避方法
  • ThreadPoolTaskExecutor+CompletableFuture实现多线程异步数据同步和自定义线程池监控和动态调整实现
  • 网络原理9-HTTP2
  • 三轴云台之运动控制系统篇
  • C++ 语言基础之数据类型详解
  • LangGraph入门教程:构建循环状态管理的LLM应用
  • 哪些方面可以做PCDN
  • Memory Repair (五)
  • SMB协议在Windows内网中的核心地位
  • Java SE - 继承与多态
  • 广东省省考备考(第二十七天6.12)—言语:逻辑填空(练习)
  • Sentinel 流量控制安装与使用
  • 【游戏设计】游戏视角类型及核心特点分析
  • 脑电震动音频震动信号模拟器设计资料:758-2路32bit DA 脑电震动音频信号模拟器
  • 单连杆倾角估计:互补滤波器的 MATLAB 仿真实现
  • 【Python打卡Day35】模型可视化与推理@浙大疏锦行
  • bindService 和 startService 生命周期对比
  • JavaWeb期末速成 Servlet
  • qemu-guest-agent详解
  • 亚马逊woot常见问题第三弹