[ABC339E] Smooth Subsequence

Link

很一眼的题。

考虑动态规划,设 dpidp_i 表示以当前这个位置为结尾能取到的最大值,满足条件的 jj 仅当 aiajD|a_i-a_j|\le Di<ji<j,转移就是:

dpi=max(dpi,dpj+1)dp_i=\max(dp_i,dp_j+ 1)

拆开那个绝对值的式子,发现 aja_j 的范围在 [aiD,ai+D][a_i-D,a_i+D] 之间,发现值域较小,考虑线段树优化,只用在枚举 ii 的时候对值域做线段树维护最大值,直接查询能取到的区间的最大值就没了,这时候线段树里面的值的更新时间都小于 ii,所以符合我们的状态,然后对线段树进行更新就完了。

#include<bits/stdc++.h>
using namespace std;
const int N =2e6+10;
int n,D,ans=1;
int d[N],a[N],dp[N];
void update(int l,int r,int s,int t,int p,int change){
	if(l<=s&&t<=r)	{d[p]=max(d[p],change);return ;}
	int mid=(s+t)>>1;
	if(l<=mid)	update(l,r,s,mid,p<<1,change);
	if(r>mid)	update(l,r,mid+1,t,p<<1|1,change);
	d[p]=max(d[p<<1],d[p<<1|1]);
}
int Query(int l,int r,int s,int t,int p){
	if(l<=s&&t<=r)	return d[p];
	int mid=(s+t)>>1,ans=0;
	if(l<=mid)	ans=max(ans,Query(l,r,s,mid,p<<1));
	if(r>mid)	ans=max(ans,Query(l,r,mid+1,t,p<<1|1));
	return ans;
}
int main(){
	cin>>n>>D;
	for(int i=1;i<=n;i++)	cin>>a[i];
	for(int i=1;i<=n;i++){
		dp[i]=max(dp[i],Query(max(1,a[i]-D),min(a[i]+D,500000),1,500000,1))+1;
		update(a[i],a[i],1,500000,1,dp[i]);
		ans=max(ans,dp[i]);
	}
	cout<<ans<<endl;
}
posted @   June_Failure  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示