「一本通 4.2 例 3」与众不同
可以预处理出每个右端点 对应的最长互不相同区间的左端点 。
假设我们已经处理出了 ,那么如果 中没有数与 相同,则 是以 结尾最长互不相同区间,反之以 结尾最长互不相同区间为 ,其中 是 上一次出现的位置,整理得
[P3901 数列找不同]
#include <bits/stdc++.h> using namespace std; int n, m; int a[100005], st[100005], len[100005], last[100005]; int main(){ scanf("%d%d" ,&n ,&m); for(int i = 1; i <= n; ++i){ scanf("%d" ,&a[i]); } for(int i = 1; i <= n; ++i){ st[i] = max(last[a[i]] + 1, st[i - 1]); last[a[i]] = i; } for(int i = 1; i <= m; ++i){ int l, r; scanf("%d%d" ,&l ,&r); if(st[r] <= l){ printf("Yes\n"); }else{ printf("No\n"); } } return 0; }
可以发现 具有单调性。
对于每次询问的区间 ,我们不知道所有以 为右端点的区间是否被 所截,因此需要求出一个值 ,使得右端点 的区间被 所截(此时最长长度为 ),右端点 的区间不会被 所截(答案为 )。
由于 具有单调性,因此可以使用二分查找 。对于 的情况可以用ST表维护。
题目中只说 ,这意味着 可能是负数,此时需要考虑将 加上 或直接离散化。
注意题目中的下标是从 开始的
#include <bits/stdc++.h> using namespace std; int n, m; int a[200005], st[200005], len[200005], last[200005]; int f[200005][20]; vector<int> rk; int query(int l, int r){ int k = log2(r - l + 1); return max(f[l][k], f[r - (1 << k) + 1][k]); } int main(){ scanf("%d%d" ,&n ,&m); for(int i = 1; i <= n; ++i){ scanf("%d" ,&a[i]); rk.push_back(a[i]); } sort(rk.begin(), rk.end()); rk.erase(unique(rk.begin(), rk.end()), rk.end()); for(int i = 1; i <= n; ++i){ a[i] = lower_bound(rk.begin(), rk.end(), a[i]) - rk.begin() + 1; } for(int i = 1; i <= n; ++i){ st[i] = max(last[a[i]] + 1, st[i - 1]); len[i] = i - st[i] + 1; f[i][0] = len[i]; last[a[i]] = i; } for(int j = 1; (1 << j) <= n; ++j){ for(int i = 1; i <= n; ++i){ f[i][j] = f[i][j - 1]; if(i + (1 << (j - 1)) <= n){ f[i][j] = max(f[i][j], f[i + (1 << (j - 1))][j - 1]); } } } for(int i = 1; i <= m; ++i){ int l, r; scanf("%d%d" ,&l ,&r); l++; r++; int mid = lower_bound(st + l, st + r + 1, l) - st; if(lower_bound(st + l, st + r + 1, l) == st + r + 1){//此时所有区间被 l 所截 printf("%d\n" ,r - l + 1); }else{ printf("%d\n" ,max(mid - l, query(mid, r))); } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现