[国家集训队] 等差子序列 题解
P2757 [国家集训队] 等差子序列 题解
首先简化题目之后,发现如果序列之中存在一个长度
对于这种长度为
所以考虑枚举每一个中间点
维护一个初始全为
可以考虑用一棵线段树维护区间的哈希值,单点修改之后用 up()
函数重新维护线段树即可。查询的时候需要注意,因为查询的区间不一定是儿子代表的区间,所以可以在返回的时候直接乘上对应的位数即可。
时间复杂度:
// Problem: P2757 [国家集训队] 等差子序列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2757
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2023-08-22 11:29:52
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#define int unsigned long long
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 5e5 + 10, base = 13331, yes = 1, no = 2;
int n, a[N], b[N], pl[N];
struct qwq {
int l, r, hl, hr;
} tr[N << 2];
void up(int u) {
tr[u].hl = tr[u << 1].hl + tr[u << 1 | 1].hl * pl[(tr[u << 1].r - tr[u << 1].l + 1)];
tr[u].hr = tr[u << 1].hr * pl[tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1] + tr[u << 1 | 1].hr;
}
void build(int u, int l, int r) {
tr[u] = {l, r, no, no};
if(l == r) return (void)(b[l] = no);
build(u << 1, l, l + r >> 1), build(u << 1 | 1, (l + r >> 1) + 1, r);
up(u);
}
void update(int u, int x) {
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if(l == r) {
b[l] = yes;
tr[u].hl = tr[u].hr = yes;
return ;
}
if(x <= mid) update(u << 1, x);
else update(u << 1 | 1, x);
up(u);
}
int query(int u, int ql, int qr, int op) {
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
if(ql <= l && qr >= r) return (op ? (tr[u].hr * pl[qr - r]) : tr[u].hl * pl[l - ql]);
int t = 0;
if(ql <= mid) t = query(u << 1, ql, qr, op);
if(qr > mid) t += query(u << 1 | 1, ql, qr, op);
return t;
}
void work() {
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
build(1, 1, n);
for(int i = 1; i <= n; i ++) {
update(1, a[i]);
int d = min(a[i] - 1, n - a[i]);
if(query(1, a[i] - d, a[i] - 1, 0) != query(1, a[i] + 1, a[i] + d, 1))
return (void)(cout << "Y\n");
}
cout << "N\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T;
cin >> T;
pl[0] = 1;
for(int i = 1; i <= N - 10; i ++) pl[i] = pl[i - 1] * base;
while(T --) work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?