Flat Subsequence

题意:给定一个数组和一个k值,要求生成一个新数组,新数组满足每个元素都来自原数组(不一定连续,但顺序不能变),并且相邻数组的差值不能超过k。问新数组最长的长度是多少

思路:从原数组的任何一个元素开始往后找都能生成一个新的数组B,所以要找出全部的B来比较长度,这里涉及到相邻元素差值不超过k,所以限制了区间相邻值的范围,往后找就是更改区间,想到单点修改和区间查询

#include<iostream>  线段树 单点修改区间查询 
#include<algorithm>
using namespace std;
typedef long long  ll;
const int maxn=3e5+10;
const ll mod=998244353;
int n,a[maxn],c[maxn],k,i;
struct node{
	int l,r;
	int v;
}tree[maxn<<2];

void update(int k)
{
	tree[k].v=max(tree[k<<1].v,tree[k<<1|1].v);
}
void build(int k,int l,int r)
{
	tree[k].l=l,tree[k].r=r,tree[k].v=0;
	if(l==r)
	return ;
	int mid=(l+r)/2;
	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
}
void modify(int k,int pos,int v)
{
	if(tree[k].l==tree[k].r)
	{
		tree[k].v=max(tree[k].v,v);
		return;
	}
	int mid=(tree[k].l+tree[k].r)/2;
	if(pos<=mid)
	modify(k<<1,pos,v);
	else
	modify(k<<1|1,pos,v);
	update(k);
}
int query(int l, int r, int k) 
{
	if (l<=tree[k].l && r>=tree[k].r){
		return tree[k].v;
	}
	int mid=(tree[k].l+tree[k].r)/2;
	int v=0;
	if(l<=mid)
	v=max(v,query(l,r,k<<1));
	if(r>mid)
	v=max(v,query(l,r,k<<1|1));
	return v;
}
int main()
{
	cin>>n>>k;
	for( i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	build(1,0,300000);
	int res=0;
	for(i=1;i<=n;i++)
	{
		int l=max(0,a[i]-k),r=min(300000,a[i]+k);
		c[i]=1+query(l,r,1);
		modify(1,a[i],c[i]);
		res=max(res,c[i]);
	}
	cout<<res<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值