#10121. 「一本通 4.2 例 3」与众不同
离线询问最大完美数列长度 这种[L,R]的题目一般都先定R 然后再一个线性递推
设f[i] 表示第i个数为完美序列结尾 开头最大的位置 明显f[]是单调递增的
明显以i结尾完美序列的最大长度就是 i-pos+1
再考虑一个询问[L,R]
对于f[i]>L的情况 就相当于询问区间最大值
特别的 可能最开始几个的f[]<L 我们要找到最后一个f[]<L的位置pos
前面几个的最大值为pos-L+1 后面最大值就区间询问RMQ即可
#include<bits/stdc++.h>
#define il inline
#define ri register int
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
const int mod=9999991;
const int maxn =2e5+5;
const int maxx =1e6;
int x,n,m;
int st[maxn][20],lg[maxn],last[(maxx<<1)+5],dp[maxn],f[maxn];
void init(){
lg[0]=-1;
for(ri i=1;i<=n;i++)
lg[i]=lg[i>>1]+1;
for(ri j=1;(1<<j)<=n;j++)
for(ri i=1;i+(1<<j)-1<=n;i++)
st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
}
int askmax(int L,int R){
if(L>R)return 0;
int k=lg[R-L+1];
return max(st[L][k],st[R-(1<<k)+1][k]);
}
int main(){
//int n,m;
scanf("%d%d",&n,&m);
for(ri i=1;i<=n;i++){
scanf("%d",&x);
f[i]=max(f[i-1],last[maxx+x]+1);
dp[i]=i-f[i]+1;
st[i][0]=dp[i];
last[x+maxx]=i;
}
init();
while(m--){
int L,R;
scanf("%d%d",&L,&R);
L++;R++;
int pos=lower_bound(f+1+L,f+1+R,L)-f-1;
//cout<<"pos="<<pos<<endl;
printf("%d\n",max(pos-L+1,askmax(pos+1,R)));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现