AtCoder Beginner Contest 338D - Island Tour【枚举】

news2025/1/18 6:43:55

原题链接:https://atcoder.jp/contests/abc338/tasks/abc338_d

Time Limit: 2 sec / Memory Limit: 1024 MB

Score: 425 points

问题陈述

AtCoder 群岛由 N 座岛屿组成,这些岛屿由 N 座桥梁连接。这些岛屿的编号从1到N,i(1≤i≤N−1)桥双向连接i和i+1岛,而N桥双向连接N和1岛。除了过桥之外,没有其他方式可以在岛屿之间旅行。

在这些岛屿上,经常会有从X1​岛出发,依次游览X2​,X3​,…,XM​岛的旅行团。游览过程中可能会经过正在游览的岛屿以外的其他岛屿,游览过程中经过桥梁的总次数定义为游览的长度*。

更确切地说,是满足以下所有条件的l+1岛屿a0​,a1​,…,al​序列,其长度定义为l:

  • 对于所有j (0≤j≤l−1),岛屿aj​和aj+1​都由一座桥直接连接。
  • 有一些 0=y1​<y2​<⋯<yM​=l,对于所有 k (1≤k≤M),ayk​​=Xk​。

由于财政困难,这些岛屿将关闭一座桥,以减少维护费用。求在最佳情况下选择关闭的桥时,可能的最小游程长度。

限制因素

  • 3≤N≤2×1e5
  • 2≤M≤2×1e5
  • 1≤Xk​≤N
  • Xk​\neqXk+1​ (1≤k≤M−1)
  • 所有输入值均为整数。

输入输出描述

Sample Input 1Copy

3 3
1 3 2

Sample Output 1Copy

2
  • 如果第一座桥关闭:以岛屿 (a0​,a1​,a2​)=(1,3,2) 为序列,可以依次游览岛屿 1,3,2,可以进行长度为 2 的游览。没有更短的游程。
  • 如果第二座桥关闭:根据岛屿(a0​,a1​,a2​,a3​)=(1,3,1,2)的顺序,可以依次游览岛屿1,3,2,可以进行长度为3的游览。没有更短的游程。
  • 如果第三座桥关闭:按照岛屿(a0​,a1​,a2​,a3​)=(1,2,3,2)的顺序,可以依次游览岛屿1,3,2,可以进行长度为3的游览。没有更短的游程。

因此,在最佳选择关闭桥梁的情况下,可能的最小游程长度为 2。

下图从左到右分别显示了关闭桥梁 1,2,3 时的情况。带数字的圆圈代表岛屿,连接圆圈的线代表桥梁,蓝色箭头代表最短旅游路线。

Sample Input 2Copy

4 5
2 4 2 4 2

Sample Output 2Copy

8

同一岛屿可能在 X1​,X2​,…,XM​ 中出现多次。

Sample Input 3Copy

163054 10
62874 19143 77750 111403 29327 56303 6659 18896 64175 26369

Sample Output 3Copy

390009

解题思路:

先画个图来描述一下:

如上图所示例子,对于任意俩个a-b,从a到b和从b到a走过的路径一定是一样的,例如[2,4],从2走到4和从4走到2走的路径的长度一定是一样的,我们不妨让x=min(a,b],y=max(a,b),对于任意一条路径a<->b<->c<->d,任意俩个点可以看作一个区间,较小的那个数为左端点,较大的那个数为右端点,我们定义俩个vector数组l,r,r[i]存储右端点为i的所有区间的左端点,l[i]存储左端点为i的所有区间的右端点,然后枚举删每一条边, 然后看当前删除的边会对哪些区间的计算造成影响,首先考虑删除n号结点到1号结点之间的边,如上图所示就是删除6号边,那么此时任意区间的计算方式都是右端点减去左端点,此时计算这种删边方式走过的路径的长度,然后考虑删除i号点和i+1号点之间的i号边,然后考虑此时会对原来的区间造成哪些影响。

  • 首先对于左端点位于i号结点的区间,那么这个区间的右端点肯定位于i号点右边,由于i号边被删除了,那么这个区间的贡献计算方式就不是右端点-左端点了,应该是先右端点走到n号点,n号点再走到1号点,然后1号点再走到左端点,所以把原来的右端点减去左端点的贡献减去,把新的贡献加上。
  • 然后对于右端点位于i号结点的区间,那么这个区间的左端点肯定位于i号点左边,由于i号边被删除了,那么这个区间的计算方式就不是先右端点走到n号点,n号点在走到1号点,然后1号点再走到左端点了,而是直接从左端点走到右端点,所以把原来的右端点->n->1->左端点的贡献减去,加上新的贡献右端点-左端点。

这样枚举删每一条边了,根据造成的影响修改贡献,然后对于所有删边情况的总贡献求一个最小值即可。

时间复杂度:枚举删除每条边时间复杂度为O(n),然后每个区间只会被使用俩次,当遇到左端点的时候使用一次,遇到右端点的时候使用一次,时间复杂度为O(m),最终时间复杂度为O(n+m)。

空间复杂度:定义了俩个vector数组l,r,l[i]表示左端点为i的所有区间的右端点,r[i]表示右端点为i的所有区间的左端点,每个区间左端点右端点各存储一次,所以空间复杂度为O(n+m)。

cpp代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
int n, m;
int a[N];
vector<int> r[N], l[N]; // l[i]表示左端点为i的所有区间的右端点,r[i]表示右端点为i的所有区间的左端点
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
        scanf("%d", &a[i]);
    LL ans = 0;
    for (int i = 2; i <= m; i++)
    {
        int x = a[i - 1], y = a[i];
        if (x > y)
            swap(x, y);    // 让x表示左端点,y表示右端点
        ans += y - x;      // 开始删n号边,所有区间贡献的计算方式都是右端点-左端点
        r[y].push_back(x); // 存储右端点是y的所有区间
        l[x].push_back(y); // 存储左端点是x的所有区间
    }

    LL sum = ans;
    for (int i = 1; i <= n; i++) // 枚举删每一条边
    {
        for (auto t : r[i])
        { // 对于右端点为i的所有区间根据删除的边修改贡献
            sum += i - t;
            sum -= (n - i + t);
        }
        for (auto t : l[i])
        { // 对于左端点为i的所有区间根据删除的边修改贡献
            sum -= t - i;
            sum += (n - t + i);
        }
        ans = min(ans, sum); // 更新答案
    }
    cout << ans << endl;
    return 0;
}

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

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

相关文章

Stable Diffusion系列(四):提示词规则与使用

文章目录 基础规则高级规则插件使用 基础规则 所谓提示词&#xff0c;也就是文生图中的文&#xff0c;由连贯的英语单词或句子组成。其最基础的规则是&#xff1a; 不同提示词之间需要用英文逗号分隔&#xff0c;空格和换行不影响读取想混合多个要素时使用|&#xff0c;相当于…

AD/DA(模数数模转换)

文章目录 前言一、介绍部分介绍AD/DA硬件电路模型硬件电路ADC模块DAC模块ADC0809DAC0832 运算放大器&#xff08;运放&#xff09;运放电路 DA原理两种不同的DA转换器 AD原理部分AD/DA性能指标XPT2046介绍主要功能XPT2046时序结构控制字节解释单端模式配置表 二、实例使用AD读取…

shell常用命令,参数传递,函数,挂载磁盘

一、shell常用命令 1、ls 功能:显示文件和目录的信息ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性,包括大小,日期,符号连接,是否可读写及是否可执行 ls -lh 显示文件的大小,以容易理解的格式印出文件大小 (例如 1K 234M2…

echarts多个折线图共用X轴,实现tooltip合并和分离

echarts共享X轴案例&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</…

数据结构(栈stack)

文章目录 一、栈1、栈的定义2、顺序栈2.1、初始化2.2、进栈2.3、出栈2.4、读取 3、链栈 一、栈 1、栈的定义 逻辑结构&#xff1a;与普通线性表相同数据的运算&#xff1a;插入、删除操作有区别 2、顺序栈 2.1、初始化 ”.”适用于结构体变量&#xff0c;”->”适用于…

【算法专题】二分查找(入门)

&#x1f4d1;前言 本文主要是二分查找&#xff08;入门&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日…

探索元宇宙的未来:数字人对话系统 - Linly-Talker —— “数字人交互,与虚拟的自己互动”

探索元宇宙的未来&#xff1a;数字人对话系统 - Linly-Talker —— “数字人交互&#xff0c;与虚拟的自己互动” 之前空闲的时候我似乎已经写过了有关于数字人的两篇文章&#xff0c;今天更多的写这篇文章就是想探索一下元宇宙的未来&#xff0c;这种数字人对话系统能做什么&…

算法沉淀——双指针算法(leetcode真题剖析)

算法沉淀——双指针算法 01.移动零02.复写零03.快乐数04.盛最多水的容器05.有效三角形的个数06.和为s的两个数字07.三数之和08.四数之和 双指针算法&#xff08;Two Pointer Algorithm&#xff09;是一种常用于数组&#xff08;或链表&#xff09;操作的算法技巧。它的核心思想…

2024年1月的论文推荐

又到月底了&#xff0c;在月初推荐论文的基础上又整理了10篇推荐阅读的论文 1、MosaicBERT https://mosaicbert.github.io/ 一种用于快速预训练的双向编码器。MosaicBERT是针对快速预训练优化的自定义BERT架构。主要架构修改:FlashAttention, ALiBi&#xff0c;门控线性单元…

【JavaWeb程序】【C00150】基于SSM的二手交易平台管理系统-(论文+PPT)

基于SSM的二手交易平台管理系统-&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目包运行、免费远程调试 项目简介 这是一个基于ssm的二手交易平台管理系统 本系统分为用户和管理员两个模块。 其中用户的权限为&#xff1a;修改个人信息、闲置商…

log4j2 java api 入门介绍

概述 Log4j 2 API 提供了应用程序应该编码的接口&#xff0c;并提供了实现者创建日志实现所需的适配器组件。 虽然 Log4j 2 在 API 和实现之间被分解&#xff0c;但这样做的主要目的不是允许多个实现&#xff0c;尽管这当然是可能的&#xff0c;而是明确定义在“正常”应用程…

探索机器学习的奥秘

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 机器学习的定义二. 机器学习的发展历程三. 机器学习的原理四. 机器学习的分类…

路由、组件目录存放

文章目录 单页应用程序&#xff1a;SPA- Single Page Application路由的介绍VuePouter的介绍VueRouted 的使用 组件目录存放问题&#xff08;组件分类&#xff09; 单页应用程序&#xff1a;SPA- Single Page Application 单页应用&#xff08;SPA&#xff09;:所有功能在一个…

四. 基于环视Camera的BEV感知算法-BEVFormer实战

目录 前言1. BEVFormer实战 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Camera的BEV感知算法&#xff0c;一起去学习下 BEVFormer 的相关代码 课程…

MySQL之索引分类,语法以及SQL性能分析(慢日志,profile,explain)

索引分类 分类含义特定关键字主键索引针对于表中主键创建的索引默认自动创建&#xff0c;只能有一个PRIMARY唯一索引避免同一个表中某数据列中的值重复可以有多个UNIQUE常规索引快速定位特定数据可以有多个全文索引全文索引查找的文本中的关键字&#xff0c;而不是比较索引中的…

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合

目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步&#xff1a;采用事件风暴。 第 2 步&#xff1a;选出聚合根。 第 3 步&#xff1a;找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步&#xff1a;画出对象的引用和依赖模型…

web前端项目-五子棋【附源码】

五子棋&#xff08;人机对弈&#xff09; 本项目【五子棋】是一款人机对弈的策略型棋类游戏。可以选择落子方&#xff1b;游戏难度和是否显示落子次序。游戏双方分别使用黑白两色的棋子&#xff0c;在棋盘直线与横线的交叉点上进行对弈。五子棋可以促进大脑发育、提高思维能力…

go语言基础之泛型

1.泛型 泛型是一种独立于所使用的特定类型的编写代码的方法。使用泛型可以编写出适用于一组类型中的任何一种的函数和类型。 1.1 为什么需要泛型 func reverse(s []int) []int {l : len(s)r : make([]int, l)for i, e : range s {r[l-i-1] e}return r }fmt.Println(reverse…

Docker—入门及Centos7安装

1、Docker入门 1.1、Docker是什么&#xff1f; Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build&#xff0c;Ship&#xff0c;and Run Any App,Anywhere”&#xff0c;也就是通过对应组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP&…

指数计算(填空)

解题思路&#xff1a; 7的2020次方很大&#xff0c;需要用BigInteger来进行运算。 pow用来算指数运算。 remainder用来算BigInteger之间的取余。 解题代码&#xff1a; public static void main(String[] args) {BigInteger xnew BigInteger ("7");BigInteger ynew…