#919. 【UR #28】环环相扣 题解

news/2025/2/25 21:11:47/文章来源:https://www.cnblogs.com/lupengheyyds/p/18737262

#919. 【UR #28】环环相扣 题解

取模不好搞,我们先分析性质。

首先可以假设 \(a_i>a_j>a_k\),那么根据“环的顺序”,可以被分成两种情况

  • \(i\to j\to k\to i:(a_i\bmod a_j)+(a_j\bmod a_k)+a_k\)

  • \(i\to k\to j \to i:(a_i\bmod a_k)+a_j+a_k\)

最优化的题,我们可以先分析一个答案下界/上界,与他们的取等条件,这样往往可以找到许多优秀的性质。

分析答案下界是很简单的,就是竭尽所想的构造一个比较优的方案。

分析答案上界需要一些数学手段,得到一种情况的答案上界,若小于等于先前分析的答案下届,那么这种情况就一定是不可取的。

由于取模很复杂,这里直接不考虑取模都可以得到一个答案下界:

考虑第二种情况,有 \(ans\ge a_{\max_2}+a_{\max_3}\),即次大值加次次大值。

根据取模的常见结论:

\(a>b\)\(a\bmod b\le \min(b-1,\frac a2,a-b)\)

得到两种情况的上界:

  • \(ans\le \min(a_j+2a_k-2,\frac {a_i}2+\frac {a_j}2+a_k,a_i,2a_j-1,\cdots)\)
  • \(ans\le \min(a_j+2a_k-1,\frac {a_i}2+a_j+a_k,a_i+a_j)\)

当然对于情况一还有更多的组合,但是形式十分复杂看上去就不怎么好分析。

我们尝试从形式最简单的那几个探究起。

  • 对于第一种情况:

    • \(ans\le a_i\) 这说明当 \(i\) 不取最大值就一定使第一种情况答案达不到上界

    • \(ans\le 2a_j-1\) 这说明 \(a_j\) 只能取次大值(因为 \(a_i\) 是最大值)否则会使答案低于下界

    • \(ans\le \min(a_j+2a_k-2,a_i-a_j+2a_k-1,\cdots)\) 太复杂了,有加减乘除还涉及多个变量,似乎并不能分析出什么。

  • 对于第二种情况:

    • \(ans\le a_i+a_j\):这说明若 \(a_i\) 只能取最大值,否则答案不会更大。
    • 其他情况同理,太复杂了。

现在根据我们的分析重新整理一下两种情况:

  • \(ans=(a_{\max}\bmod a_{\max_2})+(a_{\max_2}\bmod a_k)+a_k\)

  • \(ans=(a_{\max}\bmod a_k)+a_j+a_k\)

可以发现第二种情况 \(a_j\) 不参与任何取模,直接取次大值一定是最优的(之前要求比 \(a_i\) 小,不能贸然得到这个结论)。

于是再次整理为:

  • \(ans=(a_{\max}\bmod a_{\max_2})+(a_{\max_2}\bmod a_k)+a_k\)

  • \(ans=(a_{\max}\bmod a_k)+a_{\max_2}+a_k\)

于是只有 \(a_k\) 是不确定的,单次枚举 \(\mathcal O(n)\),总复杂度 \(\mathcal O(nq)\)。有 \(30\) 分。

如果已经分析了很多性质了,应该尝试一些算法去解决。(分析不出来任何性质也只能套算法呀QWQ)

我们已经把单次查询的复杂度降到最低了(与输入同级了),那么现在要考虑预处理些什么。

发现我们每次其实是在找 \(\max_{k\in [l,r]\setminus\{\max,\max_2\}}\{(a_{\max_2}\bmod a_k)+a_k\}\)\(\max_{k\in [l,r]\{\max,\max_2\}}\{{(a_{\max}\bmod a_k)+a_k}\}\)

可以预处理这两坨。

\(F_1[l][r],F_2[l][r]\) 表示这两坨,尝试整体转移,然后就失败了。

因为 \(a_{\max}\)\(a_{\max_2}\) 是不断变化的,\(F_1,F_2\) 不能继承之前的答案。

这提示我们固定这两个值,有一种神奇的方法

\(F([l,r],i)\) 表示 \(\max_{k\in [l,r]\setminus\{i,\max\}}\{{(a_i\bmod a_k)+a_k}\}\)

然后我们用 \(F([l,i-1],i),F([i+1,r],r)\) 合并出 \(F([l,r],i)\)

这种设 \(F([l,r],i)\) 并处理 \(F([l,i-1]),i),F([i+1,r],r)\) 是一种非常实用的方法,在莫队二次离线中也用了类似的思路。

发现我们可以 \(F([l+1,i-1],i)\to F([l,i-1],i)\)

具体的,设 \([l+1,i]\) 中的最大值下标为 \(t\)

  • \(a_l\le a_t\)\(F([l,i-1],i)=\max((a_i\bmod a_l)+a_k,F([l+1,i-1],i))\)

  • \(a_l>a_t\)\(F([l,i-1],i)=\max((a_i\bmod a_t)+a_k,F([t+1,i-1],i)),t\leftarrow l\)

类似的处理出 \(F([i+1,r],i)\),然后合并出 \(F([l,r],i)\) 注意这里需要特判两边的最大值

复杂度 \(\mathcal O(n^2+q)\)。可以多得 \(10\)

有了新的做法,根据做法分析新的性质(悲

首先发现如果 \([l,i-1]\) 中有两个数大于 \(a_i\) 那么就没必要处理了,因为 \(a_i\) 不会作为这个区间的最大值或次大值。

我们可以在尝试一下答案上下界:\(ans\le a_i\)。当 \(\frac{a_i}2<a_k\le a_i\) 的时候取等,即:若存在两个 \(a_k\) 满足那个不等式也不用搜索了。

假设我们已经知道结论后进一步分析,我们一开始假设从每个 \(i\) 开始,往左/右都恰好走移动两步。如果在 \(k\) 位置要使 \(i\) 的贡献多走一步,\(a_k\) 必定 \(\le \frac {a_i}2\),并且这对于每个 \(i\)不独立的即若存在 \(k<j<i\) 使得 \(j\) 多贡献 \(i\) 一步,\(k\) 多贡献 \(i,j\) 各一部。那么 \(a_k\le \frac {a_j}2\le \frac {a_i}4\)

感性理解,这样只会减小 $\log $ 次。

如果各种计算的次数的限制是不独立的,我们可以考虑势能分析

令势能为 \(a_{\max}^n\) 那么每多移动一步,每多移动一步,其势能就会除以 \(2\)。所以总共多移动 \(\log_2a_{\max}^n=\mathcal O(n\log a)\) 次,算上本来的 \(4n\) 次。预处理复杂度 \(\mathcal O(n\log a)\)

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

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

相关文章

Spring复习-事务

事务概述 Spring事务编程概述 事务是开发中必不可少的东西,使用JDBC开发时,我们使用connnection对事务进行控制,使用MvBatis时,我们使用SqlSession对事务进行控制,缺点显而易见,当我们切换数据库访问技术时,事务控制的方式总会变化,Spring 就将这些技术基础上,提供了统…

Prompt进阶

在Prompt入门里,我们分享了OpenAI官方给出的提示词建议,但这些建议基本上是指导性的,方向性的,概念性的,虽然对我们编写提示词有很大帮助,但究竟我们的提示词好还是不好,效率怎么性,很大程度上要看每个人的理解,和提示词输出。那么有没有一个可操作性的,方法论的,谁…

P1174 打砖块

链接 https://www.luogu.com.cn/problem/P1174 思路刚开始的思路:设置dp[i][j]:前i列使用了j颗子弹,那么递推dpi,j=max(dpi,j,dpi-1,k+maxj-k),然后统计在第i列使用了j-k颗子弹会多出来多少颗,把这些遍历加到前面,见代码。喜提70pts。但是搞不懂哪里错了。 看了评论区的dp:70…

redis - [06] redis-benchmark性能测试

题记部分 001 || 参数含义 002 || 测试100个并发,100000个请求 启动redis-server redis-server /etc/redis.conf 进行性能测试 redis-benchmark -h localhost -p 6379 -c 100 -n 100000

百万架构师第四十三课:Nginx:Nginx 应用实战|JavaGuide

百万架构师系列文章阅读体验感更佳 原文链接:https://javaguide.net 公众号:不止极客 课程目标:Nginx 反向代理功能配置 Nginx 负载均衡实战 Nginx 动静分离配置 Nginx 配置文件分析 Nginx 多进程模型原理 Nginx 高可用集群实战反向代理​ 我们把请求发送到 proxy (代理服务…

大三下每日打卡003

今天配置了python的虚拟环境anaconda想尝试一下yolov8来实现识别

需求评审

需求评审是产品经理日常会议的形式之一,也是一个“公开处刑”的时刻。这篇文章,我们看看作者分享的如何做好一次需求评审的经验,供大家参考。前段时间有小伙伴留言,想聊一下关于需求评审面向不同角色如何处理,以及产品不同生命周期产品工作上有什么区别。我结合自己工作经…

牛客题解 | 对称的二叉树_1

牛客题库题解题目 题目链接 题目的主要信息:判断一棵二叉树是否是镜像,即判断二叉树是否是轴对称图形轴对称:非轴对称:举一反三: 学习完本题的思路你可以解决如下题目: BM28. 二叉树的最大深度 BM29. 二叉树中和为某一值的路径(一) BM32. 合并二叉树 BM33. 二叉树的镜像…

牛客题解 | 字符串变形

牛客题库题解题目 题目链接 题目主要信息:将字符串大小写反转 将整个字符串的所有单词位置反转举一反三: 学会了本题的思路,你将可以解决类似的字符串问题: BM84. 最长公共前缀 BM85. 验证IP地址 方法一:双逆转(推荐使用) 思路: 将单词位置的反转,那肯定前后都是逆序,…

牛客题解 | 在二叉树中找到两个节点的最近公共祖先

牛客题库题解题目 题目链接 题目的主要信息:给定一棵二叉树以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点 二叉树非空,且每个节点值均不同举一反三: 学习完本题的思路你可以解决如下题目: BM29. 二叉树中和为某一值的路径(一) BM37. …

牛客题解 | 反转链表_1

牛客题库题解题目 题目链接 题目的主要信息:给定一个长度为\(n\)的链表,反转该链表,输出表头举一反三: 学习完本题的思路你可以解决如下题目: JZ6. 从尾到头打印链表 方法一:迭代(推荐使用) 思路: 将链表反转,就是将每个表元的指针从向后变成向前,那我们可以遍历原始…

牛客题解 | 判断链表中是否有环

牛客题库题解题目 题目链接 题目主要信息:给定一个链表的头节点,判断这个链表是否有环 环形链表如下所示:举一反三: 学习完本题的思路你可以解决如下题目: BM4.合并有序链表 BM5.合并k个已排序的链表 BM7.链表中环的入口节点 BM8.链表中倒数最后k个节点 BM9.删除链表的倒数…