构造矩形

news/2025/3/10 20:05:47/文章来源:https://www.cnblogs.com/phuzzz/p/18763538

构造矩形

题目描述

现有 \(n\) 条长度为 \(m\) 的线段,垂直于 x 轴分布,且互不重合。第 \(i\) 条线段的两个端点均为整数点,分别为 \((a_i, 0)\)\((a_i, m)\)。每条线段上有 \(m+1\) 个整数点,纵坐标分别为 \(0, 1, 2, …, m\)

现在,你需要选择两条不同的线段,并在每一条线段上各选择两个不同的整数点,要求这四个点连接构成的四边形恰好是一个矩形,且矩形的长减去宽为 \(k\)。请问一共有多少种选择方案?

输入描述:

第一行输入三个整数 \(n, m, k (1 ≤ n, m ≤ 10^5; 1 ≤ k < m)\) 代表线段条数、线段的长度、要求构成的矩形长宽之差。

第二行输入 \(n\) 个整数 \(a_1, a_2, …, a_n (1 ≤ a_1 < a_2 < ⋯ < a_n ≤ 10^5)\) 代表第 \(i\) 条线段端点的横坐标。

输出描述:

输出一个整数,代表一共有多少种选择方案。我们可以证明,答案不会超过 \(1e18\)

示例 1

输入:

3 2 1
1 2 3

输出:

4

说明:

在这个样例中,四种不同的选择方案如下图所示:

示例 2

输入:

6 9 4
1 2 3 4 5 8

输出:

70

题解

考虑通过枚举左侧线段 \(a_i\) 和右侧线段 \(a_j\) 构成矩形,记长为 \(l\) 宽为 \(w\) 分以下两种情况:

  • \(w = a_j - a_i\)\(l = w + k = a_j - a_i + k\)

    固定 \(a_i\) 向右枚举 \(a_j\) ,通过上下移动矩形,每一个合法的 \(a_j\) 可以有 \(m - l + 1\) 的贡献。因此第一部分总贡献如下。

    \[\sum_{i=1}^{n}\sum_{j=i+1}^{n}[(m-l+1)\cdot(m-l+1>0)] \]

    可得

\[\sum_{i=1}^{n}\{[\sum_{j=i+1}^{n}(m+a_i-k+1)-\sum_{j=i+1}^{n}a_j]\cdot(m+a_i-k+1>a_j))\} \]

​ 由于向右遍历 \(a_j\)\(l\) 单调变大。可用二分通过 \(m+a_i-k+1>a_j\) 确定最大的下标 \(j\) ,记 \(a_i\) 对应的 最大下标 \(j\)\(R_i\)

​ 可得

\[\sum_{i=1}^{n}[(R_i-i)\cdot(m+a_i-k+1)-\sum_{j=i+1}^{R_i}a_j] \]

​ 可通过前缀和进一步简化处理 \(\sum_{j=i+1}^{R_i}a_j\) ,记 \(a\) 的前缀和数组为 \(pref\)

​ 则最终简化得

\[\sum_{i=1}^{n}[(R_i-i)\cdot(m+a_i-k+1)-(pref_{R_i} - pref_i)] \]

  • \(l = a_j - a_i\)\(w = l - k = a_j - a_i - k\)

​ 与上一种情况的区别仅为 \(k\) 的符号,此外注意到,此时可能出现 \(w\leqslant 0\) 的不合法情况。可得第二部分总贡献为

\[\sum_{i=1}^{n}\sum_{j=i+1}^{n}[(m-w+1)\cdot(m-w+1>0)\cdot(w>0)] \]

​ 记 \(a\) 的前缀和数组为 \(pref\)\(a_i\) 对应的 最小、最大下标 \(j\) 分别为 \(L_i\)\(R_i\) ,分别由 \(w = l - k = a_j - a_i - k >0\)\(m-w+1 = m-a_j+a_i+k+1 >0\) 求得。然后还需要满足 \(R_i > L_i\) 最后简化得

\[\sum_{i=1}^{n}\{[(R_i-L_i+1)\cdot(m+a_i+k+1)-(pref_{R_i} - pref_{L_i-1})]\cdot(R_i > L_i)\} \]

答案即两部分之和,

代码

#include <iostream>
#include <algorithm>
using namespace std;
using ll = long long;const ll N = 1e5 + 5;
ll n, m, k, a[N], pref[N];int main() {cin >> n >> m >> k;for (int i = 1; i <= n; i++) {cin >> a[i];pref[i] = pref[i - 1] + a[i];}ll ans = 0;// a[j] - a[i] 为长方形的宽for (ll i = 1;i <= n;i++){ll R = lower_bound(a + 1,a + n + 1,m+a[i]-k+1) - a;R--;ans += (R - i) * (m + a[i] - k + 1) - (pref[R] - pref[i]);}// a[j] - a[i] 为长方形的长for (ll i = 1;i <= n;i++){ll R = lower_bound(a + 1,a + n + 1,m+a[i]+k+1) - a;ll L = upper_bound(a + 1,a + n + 1,a[i]+k) - a;R--;if (L > R) continue;ans += (R - L + 1) * (m + a[i] + k + 1) - (pref[R] - pref[L -1]);}cout << ans << endl;
}
后记

有点累的,写的最长的一篇了

快写完了没保存以为要重写,没开自动保存但发现Typora还收着我的草稿救了我一命 ´ᯅ`

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

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

相关文章

Llama 4 即将发布,引入语音能力;AI 智能运动眼镜 BleeqUp:实时对讲、AI 自动成片等功能丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看点的 活动 」,但内容仅代表编辑…

BigDecimal类--java进阶day05

1.BigDecimal出现的原因2.BigDecimal的创建不推荐第一种形式,会有误差第二种方式创建对象第三种方式调用方法2.BigDecimal常用方法除法的特殊事项 如果有除不尽的情况,常规的除法会出现问题divide的另一种方法 divide还有一个重载方法,可以解决除不尽的问题舍入模式中,进一…

3.10 学习记录

实现了员工页面的前端代码实现点击查看代码 <script setup> import { ref, onMounted } from vue import axios from axiosconst searchEmp = ref({name: ,gender: ,job: , })onMounted(() => {search(); })const search = async () => {const url = `https://web-…

transformer 中的掩码类型

知识是我们已知的也是我们未知的基于已有的知识之上我们去发现未知的由此,知识得到扩充我们获得的知识越多未知的知识就会更多因而,知识扩充永无止境

如何设计、维护和推广 API:专业人士的实用指南

API 在今天的数字化环境中扮演着至关重要的角色,它们作为系统和应用程序之间的连接纽带。对于公司而言,打造用户喜爱的 API、有效地维护它们并成功地在内部和外部推广,不仅能提高数字价值,还能带来巨大的业务收益。 API 设计是创建一个标准化、易于理解且稳定的应用程序接口…

springboot引入nacos

springboot引入nacos 一、 环境准备(windows为例)安装nacos(github镜像网址:Releases alibaba/nacos) 推荐下载发行版启动nacos本地服务 下载完毕,建议解压到没有中文路径的文件夹,在bin目录下打开cmd对话框输入下面命令启动nacos startup.cmd -m standalone启动成功出现以…

95%开发者不知道的调试黑科技:Apipost让WebSocket开发效率翻倍的秘密

在现代 Web 开发中,Websocket 作为一种常见的 Web 协议,与 Restful API 有着本质的不同。Restful API是基于请求-响应模式的单向通信,而 WebSocket 提供全双工通信渠道,允许客户端和服务器之间进行实时双向数据传输。这种特性使得它在需要实时交互的场景中大放异彩,比如 I…

题解:P9221 「TAOI-1」Pentiment

P9221 解题报告 一眼线段树优化 dp,但是调了7h。 首先考虑朴素 dp,设 \(dp_{i,j}\) 表示走到第 \(i\) 行第 \(j\) 列的方案数,转移: \[dp_{i,j}=\sum dp_{i-1,k} \]其中 \(k\) 表示第 \(i\) 行可以走到 \(j\) 的列。 比如如果第 \(i\) 行是下面这种情况:当 \(j=3\) 时,\(…

【Java开发】Tools4AI:一个适用于企业Java应用的开源智能体框架

一、简介 GitHub主页:(https://github.com/vishalmysore/Tools4AI) Tools4AI 是一个基于 Java 的开源智能体框架,它为企业Java应用程序提供了一种集成人工智能的独特方法。作为一个大型动作模型(Large Action Model,LAM)智能体,Tools4AI 能够根据自然语言指令自主执行任务…

英语328个词缀和词根汇总(14张图)

在所有的单词记忆法中,构词法是最科学、记忆效果最佳的词汇记忆法。下面整理了高中常用的词根、词缀。利用有限的词根、词缀对英语单词进行构词分析和解形释义,单词变得好认又好记,词义也一目了然。通过构词法记单词,可以举一反三,记一识十,从而达到事半功倍的记忆效果。…

No.48 ES6---数组扩展之扩展运算符和新增方法

一、数组扩展之扩展运算符 1.扩展运算符扩展运算符(spread)是三个点(…)。将一个数组转为用逗号分隔的参数序列。<script>var arr = [10,23,45,6,7];//以前获取数组中的每个元素for(let i = 0;i<arr.length;i++){console.log(arr[i]);}//有了扩展运算符之后console.lo…