2022ICPC南京站 B. Ropeway

也许更好的阅读体验

D e s c r i p t i o n \mathcal{Description} Description
n + 2 n+2 n+2个点编号 0 ~ n + 1 0~n+1 0n+1,每个点有点权,要求选若干个点使得总点权最小,其中编号为 0 0 0 n + 1 n+1 n+1的点必须选且点权为 0 0 0,同时满足任意两个被选的点之间的距离不超过 k k k,此外还会给一个 01 01 01串,表示 1 ~ n 1~n 1n这些点是否为必选的点
现在会给 m m m个询问,每个询问为如果将编号为 x x x的点权修改为 v v v的答案会是什么
多组数据
n ≤ 5 × 1 0 5 , ∑ n ≤ 2 × 1 0 6 , 1 ≤ m , k ≤ 3 × 1 0 3 , ∑ m = ∑ k ≤ 1 0 4 n\le 5× 10^5,\sum n\le 2×10^6,1\le m, k\le 3×10^3,\sum m=\sum k\le10^4 n5×105,n2×106,1m,k3×103m=k104

S o l u t i o n \mathcal{Solution} Solution
最近做做往年 I C P C ICPC ICPC题,这题算是个金牌题,做的快可以摸金的那种,意外地发现很简单
没有修改的话是个很经典的单调栈优化 D P DP DP
f i f_i fi表示 [ 0 , i ] [0,i] [0,i]这个区间满足条件且在i选了i的最小花费,转移方程为 f i = m i n { f j } f_i=min\{f_j\} fi=min{fj},这个过程单调栈优化可以做到 O ( n ) O(n) O(n),其中 j j j属于 [ i − k , i − 1 ] [i-k,i-1] [ik,i1]
对于某个位置必须选择,那么就在计算该位置的 d p dp dp值后将单调栈清空再将该位置放进去,相当于之后的选择一定有这个位置了
正着做和反着做差不多,再设 g [ i ] g[i] g[i]表示满足 [ i , n + 1 ] [i,n+1] [i,n+1]这个区间的最小花费,则答案就是 m i n { f i + m i n { g j } } min\{f_i+min\{g_j\}\} min{fi+min{gj}}
考虑修改某个位置的值,因为任意一个长度为 k k k的区间一定有一个必须选,因此当修改一个位置的值时,只要从那个位置开始往后走 k k k步算一次 f i + m i n { g j } f_i+min\{g_j\} fi+min{gj}就可以算出答案,这样复杂度是 O ( m k ) O(mk) O(mk),是满足题意的
现在问题就是怎么在修改后 O ( 1 ) O(1) O(1)的算出 f i f_i fi,首先考虑到如果把所有到 i i i的单调栈存下来,修改了 i i i位置后就从这个单调栈重新做一次,但是这样时空都不满足要求,为了解决这个问题,可以将询问都排序,这样就可以共用那个单调栈了

C o d e \mathcal{Code} Code

#include <cstdio>
#include <algorithm>
#define ll long long
#define inf 112345678901234567
using namespace std;
const int maxn = 5e5 + 10;
struct IO {template <class T>IO operator>>(T &res) {res = 0;char ch;bool flag = false;while ((ch = getchar()) > '9' || ch < '0')	flag |= ch == '-';while (ch >= '0' && ch <= '9')	res = (res << 3) + (res << 1) + (ch ^ '0'), ch = getchar();if (flag)	res = ~res + 1;return *this;}
} cin;
int T, n, m, k, hd, ed;
int a[maxn], q[maxn], q2[maxn], fr[maxn], x[maxn], v[maxn], id[maxn];
ll f[maxn], tf[maxn], g[maxn], ans[maxn];
char s[maxn];
bool cmp (int a, int b) { return x[a] < x[b]; }
int main ()
{cin >> T;while (T--) {cin >> n >> k;for (int i = 1; i <= n; ++i)    cin >> a[i];scanf("%s", s + 1);a[0] = a[n + 1] = f[0] = 0;q[hd = ed = 1] = 0;for (int i = 1; i <= n + 1; ++i) {while (q[hd] < i - k)   ++hd;f[i] = f[q[hd]] + a[i];if (s[i] == '1')    q[hd = ed = 1] = i;else {while (ed >= hd && f[q[ed]] >= f[i]) --ed;q[++ed] = i;}}q[hd = ed = 1] = n + 1, fr[n + 1] = n + 1, g[n + 1] = 0;for (int i = n; i >= 0; --i) {while (q[hd] > i + k)   ++hd;g[i] = g[q[hd]] + a[i];fr[i] = q[hd];if (s[i] == '1')    q[hd = ed = 1] = i;else {while (ed >= hd && g[q[ed]] >= g[i]) --ed;q[++ed] = i;}}cin >> m;for (int i = 1; i <= m; ++i)    scanf("%d%d", &x[i], &v[i]), id[i] = i, ans[i] = inf;sort(id + 1, id + m + 1, cmp);q[hd = ed = 1] = 0;int cur = 1;for (int i = 1; i <= n; ++i) {while (q[hd] < i - k)   ++hd;while (x[id[cur]] == i && cur <= m) {int hd2 = hd, ed2 = ed, t = a[i];a[i] = v[id[cur]];for (int j = hd; j <= ed; ++j)  q2[j] = q[j];int mx = min(i + k, n + 1);for (int j = i; j <= mx; ++j) {while (q2[hd2] < j - k)   ++hd2;tf[j] = tf[q2[hd2]] + a[j];ans[id[cur]] = min(ans[id[cur]], tf[j] + g[fr[j]]);if (s[j] == '1')    q2[hd2 = ed2 = 1] = j;else {while (ed2 >= hd2 && tf[q2[ed2]] > tf[j]) --ed2;q2[++ed2] = j;}}a[i] = t;++cur;}tf[i] = tf[q[hd]] + a[i];if (s[i] == '1')    q[hd = ed = 1] = i;else {while (ed >= hd && f[q[ed]] > f[i]) --ed;q[++ed] = i;}}for (int i = 1; i <= m; ++i)    printf("%lld\n", ans[i]);}return 0;
}

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧

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

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

相关文章

unity行为决策树实战详解

一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型&#xff0c;它将游戏AI的行为分解为一系列的决策节点&#xff0c;并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中&#xff0c;每个节点都代表一个行为或决策&#xff0c;例如移动、攻击、逃跑等…

SpringBoot3 整合Prometheus + Grafana

通过Prometheus Grafana对线上应用进行观测、监控、预警… 健康状况【组件状态、存活状态】Health运行指标【cpu、内存、垃圾回收、吞吐量、响应成功率…】Metrics… 1. SpringBoot Actuator 1. 基本使用 1. 场景引入 <dependency><groupId>org.springframew…

C#设计模式之---单例模式

单例模式&#xff08;Singleton&#xff09; 单例模式&#xff0c;属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例。 1&#xff09;普通单例模式 using System; namespace SingletonPattern {/// /// 单例模式(非线程安全)/// …

Docker Compose 使用方法

目录 前言 安装 Docker Compose Ubuntu 安装与更新 Red Hat 安装与更新 验证是否安装 Docker Compose 创建 docker-compose.yml 文件 创建一个MySQL 与 tomcat 示例 使用Docker Compose启动服务 前言 Docker Compose 是一个工具&#xff0c;旨在帮助定义和 共享多容器…

开源全文搜索引擎汇总

1、Apache Lucene Java 全文搜索框架 许可证:Apache-2.0 开发语言:Java 官网:https://lucene.apache.org/。Apache Lucene 是完全用 Java 编写的高性能、功能齐全的全文检索引擎架构,提供了完整的查询引擎和索引引擎、部分文本分析引擎。目的是为软件开发人员提供一个简单…

CADintosh X for mac CAD绘图软件2D CAD 程序 兼容 M1

CADintosh X for Mac是一个功能强大的2D CAD绘图程序&#xff0c;专为Mac用户设计。它由Lemke Software开发&#xff0c;提供了一套丰富的工具和功能&#xff0c;使用户能够轻松创建高质量的技术图纸&#xff0c;平面图和设计。 CADintosh X for Mac具有直观的用户界面&#x…

【架构】Java 系统架构演进的思考

文章目录 1 前言2 单体应用架构3 垂直应用架构4 分布式架构5 SOA 架构6 微服务云架构7 总结 1 前言 随着移动互联的发展&#xff0c;网站、H5、移动端的应用规模也不断扩大&#xff0c;不管是应用的数量还是质量都得到了指数级的提升。开发者的数量与日俱增&#xff0c;应用的…

OPENCV C++(六)canny边缘检测+仿射变换+透射变换

图像的缩放 resize(image, image, Size(round(image.cols * 0.5), round(image.rows * 0.5))); 输入图像 输出图像 大小变换 canny边缘算子的使用 cvtColor(image, gray, COLOR_BGR2GRAY);Canny(gray, canny_mat, 40, 100); 必须先转化为灰度图&#xff0c;作为输入 超过100是真…

利用docker run -v 命令实现使用宿主机中没有的命令

利用docker run -v 命令实现使用宿主机中没有的命令 使用容器中的jar命令解压jar包&#xff0c;并将解压内容输出到挂载在宿主机中的目录里 使用容器中的jar命令解压jar包&#xff0c;并将解压内容输出到挂载在宿主机中的目录里 docker run -it --name java -v /www/temp/java…

docker安装ES

拉取镜像文件 sudo docker pull elasticsearch:7.12.0 创建容器挂载目录 sudo mkdir -p /home/elasticsearch/config sudo mkdir -p /home/elasticsearch/data sudo mkdir -p /home/elasticsearch/plugins elasticsearch.yml http.host: 0.0.0.0 创建容器 sudo docker r…

.net core ConfigureServices和Configure

在.NET Core应用程序中&#xff0c;ConfigureServices和Configure方法在Startup类中起着重要的作用。 ConfigureServices方法用于进行依赖注入的配置。在该方法内&#xff0c;你可以注册应用程序所需要的各种服务、中间件和其他依赖项。它接收一个IServiceCollection参数&…

九、用 ChatGPT 提高算法和编程能力

目录 一、实验介绍 二、背景 三、LeetCode 刷题带来的问题 四、ChatGPT 如何帮助刷题 五、ChatGPT 推荐学习资源

SpringMVC -- REST风格开发,RESTful快速开发、RESTful注解开发

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 REST 一、REST简介1.1REST风格简介 二、RESTful入门案例2.…

memcpy、memmove、memcmp、memset函数的作用与区别

一、memcpy与memmove 1、memcpy 作用&#xff1a;从source的位置开始向后复制num个字节的数据到destination的内存位置。 注意&#xff1a; memcpy() 函数在遇到 ’\0’ 的时候不会停下来(strcpy字符串拷贝函数在遇到’\0’的时候会停下来)&#xff1b;destination和source…

机器视觉工程师,代码键盘侠们你们真的懂键盘吗?

机器视觉-基本知识-中英通用术语 键盘是用于操作计算机设备运行的一种指令和数据输入装置,也指经过系统安排操作一台机器或设备的一组功能键(如打字机、电脑键盘)。键盘也是组成键盘乐器的一部分,也可以指使用键盘的乐器,如钢琴、数位钢琴或电子琴等,键盘有助于练习打字。…

笛卡尔积文本的python处理

一 背景 大致背景是这样的&#xff0c;笔者在做数据处理时&#xff0c;遇到一个棘手的事情&#xff0c;主要遇到如下字符串拼接变动的场景&#xff0c;场景主要为&#xff0c;需要考虑如下两张表的组合&#xff1a; 表1-原始文本样式 序号文本样式1A变量B2A变量C3A变量CD4E变…

java的String类详解

目录 不可变字符串字符串常量池 String类的继承关系String类的底层实现创建String对象字符串拼接常见面试题 String的常用方法字符串是否相等获取子串返回字符串的长度字符串的比较返回给定值的索引转换大小写返回给定索引的字符字符串替换把字符串转换为字符数组去字符串空白字…

ant.design 组件库中的 Tree 组件实现可搜索的树: React+and+ts

ant.design 组件库中的 Tree 组件实现可搜索的树&#xff0c;在这里我会详细介绍每个方法&#xff0c;以及容易踩坑的点。 效果图&#xff1a; 首先是要导入的文件 // React 自带的属性 import React, { useMemo, useState } from react; // antd 组件库中的&#xff0c;输入…

如何使用 reqwest 包

GET 请求 向连接发起一个 GET 请求&#xff1a;https://hacker-news.firebaseio.com/v0/topstories.json&#xff0c;并解析返回的内容。 尝试发起请求 因为是 GET 请求&#xff0c;可以先在浏览器中进行查看&#xff0c;浏览器可以正常显示一个 id 列表&#xff0c;如下所示…