尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

P2757 [国家集训队] 等差子序列 题解

P2757 [国家集训队] 等差子序列 题解
📅 发布时间:2026/6/20 2:10:19
Solution

Link

好题。考虑简化题意:找一个 \(|p| \geq 3\) 的序列 \(p\) 使得 \(A_{p_i}\) 呈现等差数列,那我们找一个三个数的等差数列就可以了。中间值是特殊的,我们枚举中间值,判断左右两边是否存在一个公差相等的等差数列项。

用到一个有用的 \(01\) 序列转换 Trick。我们从左到右遍历 \(A\),同时维护出一个 \(01\) 串 \(b\),每次扫描到 \(A_i\) 就将 \(b\) 中对应的 \(i\) 位设置成 \(1\)。考虑一组等差数列存在且公差为 \(k\),这意味着 \(A_i - k, A_i + k \in [1, n]\) 同时前一项出现了,后一项尚未出现,即 \(b_{A_i - k} = 1\) 且 \(b_{A_i + k} = 0\),此时 \(A_i - k, A_i, A_i + k\) 顺序排列形成公差为 \(k\) 的长度为 \(3\) 的等差数列。

现在的问题是怎么维护或者说高效判断出有存在于左右两边的符合公差要求的项。我们再次转化问题为检查 \(b\) 是否关于 \(A_i\) 呈现中心对称。如果以 \(A_i\) 为中心的对称区间不是回文,则存在某个 \(k\) 使得 \(A_i - k\) 和 \(A_i + k\) 一个在左一个在右,反之如果是回文的,意味着对于每个 \(k\),\(A_i - k, A_i + k\) 要么都出现要么都不出现。

现在新的问题是如何快速判断回文串?常规的,使用字符串哈希。维护一棵线段树支持带修查询的字符串哈希值,对于 \(A_i\),我们计算正序哈希 \(H_{[A_i - k, A_i - 1]}\) 和逆序哈希 \(H'_{[A_i + 1, A_i + k]}\),如果 \(H = H'\) 则存在回文。实现上,注意逆序哈希的线段树合并顺序。

#include <bits/stdc++.h>using i64 = long long;
using u64 = unsigned long long;constexpr int N = 6e5 + 7;
constexpr u64 B = 13331;int n;
int a[N];
u64 b[N];struct SegTree {struct node {int l, r;u64 v1, v2;} tr[N << 2];#define ls(o) (o << 1)#define rs(o) (o << 1 | 1)void pushup(const int o) {int len_r = tr[rs(o)].r - tr[rs(o)].l + 1;int len_l = tr[ls(o)].r - tr[ls(o)].l + 1;tr[o].v1 = tr[ls(o)].v1 * b[len_r] + tr[rs(o)].v1;tr[o].v2 = tr[rs(o)].v2 * b[len_l] + tr[ls(o)].v2;}void build(int o, int l, int r) {tr[o].l = l, tr[o].r = r; tr[o].v1 = tr[o].v2 = 0;if (l == r) {return;}int mid = (l + r) >> 1;build(ls(o), l, mid);build(rs(o), mid + 1, r);}void update(int o, int l, int r, int p) {if (l == r) {tr[o].v1 = tr[o].v2 = 1;return;}int mid = (l + r) >> 1;if (p <= mid)update(ls(o), l, mid, p);elseupdate(rs(o), mid + 1, r, p);pushup(o);}u64 query1(int o, int l, int r, int ql, int qr) {if (ql <= l && r <= qr) {return tr[o].v1 * b[qr - r];}int mid = (l + r) >> 1;u64 res = 0;if (ql <= mid)res += query1(ls(o), l, mid, ql, qr);if (qr > mid)res += query1(rs(o), mid + 1, r, ql, qr);return res;}u64 query2(int o, int l, int r, int ql, int qr) {if (ql <= l && r <= qr) {return tr[o].v2 * b[l - ql];}int mid = (l + r) >> 1;u64 res = 0;if (qr > mid)res += query2(rs(o), mid + 1, r, ql, qr);if (ql <= mid)res += query2(ls(o), l, mid, ql, qr);return res;}
} seg;void init() {b[0] = 1;for (int i = 1; i < N; i++) {b[i] = b[i - 1] * B;}
}void solve() {std::cin >> n;for (int i = 1; i <= n; i++) {std::cin >> a[i];}seg.build(1, 1, n);for (int i = 1; i <= n; i++) {int t = a[i]; int len = std::min(t - 1, n - t);if (len > 0) {u64 h1 = seg.query1(1, 1, n, t - len, t - 1);u64 h2 = seg.query2(1, 1, n, t + 1, t + len);if (h1 != h2) {std::cout << "Y\n";return;}}seg.update(1, 1, n, t);}std::cout << "N\n";
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int t;std::cin >> t;init();while (t--) {solve();}return 0;
}

相关新闻

  • claude code+openspec开发java代码基本流程
  • 【C】结构体赋值
  • 模拟赛 29

最新新闻

  • 2026年天津GEO优化服务商推荐指南 - GEO优化
  • 2026年近期陕西消防:专业消防技术服务商选择与推荐 - 品牌鉴赏官2026
  • 小米手表表盘设计入门指南:Mi-Create让你轻松打造个性表盘
  • 3分钟免费汉化Axure RP:新手终极中文界面配置指南
  • 如何在Mac上5分钟制作Windows启动盘:WinDiskWriter终极指南
  • 深圳2026年6月GEO优化公司Top5:全面对比实力与落地效果 - GEO优化

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号