My Luogu

「一本通 4.2 例 3」与众不同

可以预处理出每个右端点 r 对应的最长互不相同区间的左端点 str

假设我们已经处理出了 sti1,那么如果 [sti1,i1] 中没有数与 ai 相同,则 [sti1,i] 是以 i 结尾最长互不相同区间,反之以 i 结尾最长互不相同区间为 [lastai+1,i],其中 lastxx 上一次出现的位置,整理得

sti=max{lastai+1,sti1}

[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 具有单调性。

对于每次询问的区间 [l,r],我们不知道所有以 i[l,r] 为右端点的区间是否被 l 所截,因此需要求出一个值 mid,使得右端点 [l,mid1] 的区间被 l 所截(此时最长长度为 midl ),右端点 [mid,r] 的区间不会被 l 所截(答案为 max{isti+1})。

由于 st 具有单调性,因此可以使用二分查找 mid 。对于 i[mid,r] 的情况可以用ST表维护。

题目中只说 |ai|106,这意味着 ai 可能是负数,此时需要考虑将 ai 加上 106 或直接离散化。

注意题目中的下标是从 0 开始的

#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;
}
posted @   lxy07830  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示