[USACO 2025 January Contest, Bronze] T3题解

news/2025/1/31 7:03:25/文章来源:https://www.cnblogs.com/2026zhaoyl/p/18693076

Cow Checkups 题解

题目大意:

对于每一个 \(c=0…n\),求出区间 \([l, r]\) 能使得翻转此区间后满足 \(\sum_{i=1}^n (a_i = b_i)\) 的值恰好为 \(c\) 的数量。

解法:

首先,我们定义两个二维数组:

  • \(s_{l, r}\) : 以 \(l\) 为中点 左右长度为 \(r\),即区间 \([l - r, l + r]\) 翻转后的重合数量
  • \(t_{l, r}\) : 以 \(l, l + 1\) 为中点 左右长度为 \(r\),即区间 \([l - r, l + r + 1]\) 翻转后的重合数量

这样方便处理每个奇、偶数长度的区间。
image

为了方便大家理解这两个数组,我来用样例讲解一下。

\(input:\)

7
1 3 2 2 1 3 2
3 2 2 1 2 3 1

第一,\(s_{3, 2}\) 等于?

根据定义,翻转区间 \([3-2,3+2] = [1,5]\)\(a\) 数组成为了:\(\textcolor{red}{1,2,2,3,1},3,2\)
\(b\) 数组重合的位置\(2,3\),故 \(s_{3,2} = 2\)

第二,\(t_{4,1}\) 等于?

根据定义,翻转区间 \([4-1,4+1+1] = [3,6]\)\(a\) 数组成为了:\(1,3,\textcolor{red}{3,1,2,2},2\)
\(b\) 数组重合的位置\(4,5\),故 \(t_{4,1} = 2\)

数据范围是 \(n \le 7500\),那么我们求这两个数组的时间复杂度只能控制在 \(\mathcal{O}(n^2)\)

由此,一个优秀的算法浮现在了我们的脑海中。

首先,初始化:

\(s_{i,0} = (a_i == b_i)\)

\(t_{i,0} = (a_i == b_{i+1}) + (a_{i + 1} == b_i)\)

so easy,就不多说了。

然后,怎么转移?

其实也不难。

\(s_{i,j} = s_{i,j-1} + (a_{i-j} == b_{i+j}) + (a_{i+j} == b_{i-j})\)

相当于 \(s_{i,j}\)\(s_{i,j-1}\) 的基础上左右各增加了一个数,只需再算左右两数翻转后是否满足 \(a_i == b_i\) 即可。

\(t_{i,j}\) 也同理。

\(t_{i,j} = t_{i,j-1} + (a_{i + j + 1} == b_{i - j}) + (a_{i - j} == b_{i + j + 1})\)

最后,就可以统计答案了。

\(a_i==b_i\) 做一个前缀和。

枚举要翻转的区间 \([l,r]\),用 \(s\)\(t\) 数组去计算翻转后的值。

而区间 \([1,l-1]\)\([r+1,n]\) 则用前缀和计算即可。

讲一下怎么实现

求出区间中点 \(mid = (l+r+1) \div 2\)

若区间长度为奇数,答案就是 \(s_{mid, mid-l}\)
若区间长度为偶数,答案就是 \(t_{mid, mid-l}\)

自己想一想,建议画图去理解一下。其实并不难。

Code:

由上面的分析,敲出了以下代码:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 7.5e3 + 10;
int a[N], b[N]; ll s[N][N], t[N][N], pre[N], ans[N];
// s[l][r] : 以 l 为中点 左右长度为 r reverse 后的重合数量
// t[l][r] : 以 l, l + 1 为中点 左右长度为 r reverse 后的重合数量
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr); cout.tie(nullptr);int n; cin >> n;for (int i = 1; i <= n; ++i)cin >> a[i];for (int i = 1; i <= n; ++i)cin >> b[i];for (int i = 1; i <= n; ++i) {s[i][0] = (a[i] == b[i]);for (int j = 1; j <= min(i - 1, n - i); ++j)s[i][j] = s[i][j - 1] + (a[i + j] == b[i - j]) + (a[i - j] == b[i + j]);}for (int i = 1; i < n; ++i) {t[i][0] = (a[i] == b[i + 1]) + (a[i + 1] == b[i]);for (int j = 1; j <= min(i - 1, n - i - 1); ++j)t[i][j] = t[i][j - 1] + (a[i + j + 1] == b[i - j]) + (a[i - j] == b[i + j + 1]);}for (int i = 1; i <= n; ++i)pre[i] = pre[i - 1] + (a[i] == b[i]);for (int l = 1; l <= n; ++l) {for (int r = l; r <= n; ++r) {int mid = (l + r) / 2;int ret = 0;if ((r - l + 1) & 1) {ret = (s[mid][mid - l]) + pre[l - 1] + pre[n] - pre[r];} else {ret = (t[mid][mid - l]) + pre[l - 1] + pre[n] - pre[r];}ans[ret] ++;}}for (int i = 0; i <= n; ++i)cout << ans[i] << "\n";return 0;
}

样例本地全过,交上去就 \(MLE\) 了,一分没有。

怎么办?难道要前功尽弃吗?不,先卡卡常。

不必要的 \(long\ long\) 去掉。\(s\)\(t\) 数组可以只留一个(即先求长度为奇数的区间,再求偶数区间)。

又写出以下代码:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 7.5e3 + 10;
int a[N], b[N];
int s[N][N], pre[N], ans[N];
// s[l][r] : 以 l 为中点 左右长度为 r reverse 后的重合数量
// s2[l][r] : 以 l, l + 1 为中点 左右长度为 r reverse 后的重合数量
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr); cout.tie(nullptr);int n; cin >> n;for (int i = 1; i <= n; ++i)cin >> a[i];for (int i = 1; i <= n; ++i)cin >> b[i];for (int i = 1; i <= n; ++i) {s[i][0] = (a[i] == b[i]);for (int j = 1; j <= min(i - 1, n - i); ++j)s[i][j] = s[i][j - 1] + (a[i + j] == b[i - j]) + (a[i - j] == b[i + j]);}for (int i = 1; i <= n; ++i)pre[i] = pre[i - 1] + (a[i] == b[i]);for (int l = 1; l <= n; ++l) {for (int r = l; r <= n; ++r) {int mid = (l + r) / 2;int ret = 0;if ((r - l + 1) & 1) {ret = (s[mid][mid - l]) + pre[l - 1] + pre[n] - pre[r];ans[ret] ++;} else ;}}for (int i = 1; i < n; ++i) {s[i][0] = (a[i] == b[i + 1]) + (a[i + 1] == b[i]);for (int j = 1; j <= min(i - 1, n - i - 1); ++j)s[i][j] = s[i][j - 1] + (a[i + j + 1] == b[i - j]) + (a[i - j] == b[i + j + 1]);}for (int l = 1; l <= n; ++l) {for (int r = l; r <= n; ++r) {int mid = (l + r) / 2;int ret = 0;if ((r - l + 1) & 1) ;else {ret = (s[mid][mid - l]) + pre[l - 1] + pre[n] - pre[r];ans[ret] ++;}}}for (int i = 0; i <= n; ++i)cout << ans[i] << "\n";return 0;
}

不出所料,通过了。

总结:

这是一道很好的铜组题目,我的这种方法稍微需要动脑,不知道是否有更简单的做法。

另外,这题也是新手练题的极佳选择。Good!

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

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

相关文章

02. Linux的基本操作

一、开启、关闭、重启和查看某个服务我们可以通过如下命令 开启、关闭、重启、查看某个服务。 sudo systemctl start | stop | restart | status 服务名如果我们可以通过查看 /usr/lib/systemd/system 目录下的文件列表来查看有哪些服务,该目录下每个文件都对应一个服务。 ls…

恭祝大家新春快乐!巳巳如意!

欢声笑语除夕夜,万家灯火庆新年, 巳蛇迎春辞旧岁,合家幸福永团圆。

寒假修行2

学了标题最多6个依次变小 以及标题的位置 添加属性 align="left | center |right" 是段落 在中间加或是换行 创建一条水平线 颜色为红色 300宽度 20高度 align默认居中 也可左右 图片 将图片保存后 src为路径 alt规定图像的替代文本 width为宽度 height为高度…

【编码】自定义通信协议——支持更多请求类型

前言 上一篇随笔"如何实现一套自定义网络协议",介绍了自定义协议的粘拆包的处理,消息体的编解码等。 其中包含一个案例,演示怎么实现一个RPC实现。 不过案例中的Request格式是固定的,实际应用中,RPC协议需要支持不同的API。 所以需要有一个字段来表示API类型,而…

Android Qcom board-id加载镜像学习

很早就听说过board-id能用来区分项目,没负责过这个,也一直没有时间去了解。board-id的可以通过gpio或者eeprom来存放,board-id也就是CDT中的部分内容,如果时gpio的方式,可配置的项目有些而且在主板上的都是hardcode,这样不利于维护。 XBL-CDT default: BOOT.XF.4.1/boot_i…

阿里云2025年免费领取300元无门槛优惠券

综合传送门详情免责声明 版权声明 交流群 公众hao服务器有什么用 服务器可以用于管理网络资源,比如控制网络访问、发送/接收电子邮件和 托管网站。服务器用于网站和大型数据库等应用,具有高速计算能力、长期可靠运行、强大的数据吞吐量、高可用性、可靠性、可扩展性和可管理性…

美团面试:MySQL为什么 不用 Docker部署?

本文原文链接 文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 …

Java 异常

目录异常介绍异常概念异常体系异常分类异常的产生过程解析异常的处理抛出异常 throwObjects 非空判断声明异常 throws捕获异常 try…catchfinally 代码块异常注意事项自定义异常概述例 异常介绍 异常概念 异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部…

macOS Sequoia 15.3 (24D60) Boot ISO 原版可引导镜像下载

macOS Sequoia 15.3 (24D60) Boot ISO 原版可引导镜像下载macOS Sequoia 15.3 (24D60) Boot ISO 原版可引导镜像下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org/blog/macOS-Sequoia-bo…

新春“码”启 | Cocos 3D 开发微信小游戏(第3天):场景搭建与游戏链路基础开发

新春开发 Cocos 3D 微信小游戏计划的第3天,包括总体设计方案,包括关卡模式、时间限制、复活机制等。接着详细展示基础框架研发,如开始场景和游戏场景(关卡一)的开发,包括创建场景、画布、立方体、材质,以及按钮的功能实现和场景切换等……今天是实施新春小游戏计划的第 …