AtCoder ABC339 E Smooth Subsequence

原题链接:E - Smooth Subsequence (atcoder.jp)

题目翻译:给你一个长度为n的序列a=(a1,a2,…,an)。求长度为a子序列的最大长度,使得任意两个相邻项之间的绝对差最多为D。序列A的子序列是指从a中删除0个或多个元素,并将其余元素按原来的顺序排列后得到的序列。

n的范围是[1,5e5],D的范围是[0,5e5],A中元素的范围是[1,5e5]。

思路:可以开一个从1到5e5的线段树,然后去查询[a[i]-D,a[i]+D]的范围内的数求最大值,并且将最大值更新到a[i]的位置。

#pragma GCC optimize(2)
#include
#define endl '\n' 
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair pii;
const int N=1e6+10;
ll p[N<<2],f[N<<2],MAX=5e5+10;
ll query(ll l,ll r,ll pl,ll pr,ll k)
{
	if(pl<=l&&r<=pr)
	{
		return f[k];
	}
	ll mid=l+r>>1;
	ll max1=0;
	if(pl<=mid)max1=max(max1,query(l,mid,pl,pr,k<<1));
	if(pr>mid)max1=max(max1,query(mid+1,r,pl,pr,k<<1|1));
	return max1;
}
void update(ll l,ll r,ll pos,ll k,ll v)
{
	if(l==r)
	{
		f[k]=max(f[k],v);
		return;
	}
	ll mid=l+r>>1;
	if(pos<=mid)update(l,mid,pos,k<<1,v);
	else update(mid+1,r,pos,k<<1|1,v);
	f[k]=max(f[k<<1],f[k<<1|1]);
}
int main()
{
    ios::sync_with_stdio(NULL);
    cin.tie(0),cout.tie(0);
    ll n,m;cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    	cin>>p[i];
	}
	for(int i=1;i<=n;i++)
	{
		ll k=query(1,MAX,max(1ll,p[i]-m),min(MAX,p[i]+m),1)+1;
		update(1,MAX,p[i],1,k);
		for(int i=1;i<=100;i++)
		{
			cout<

你可能感兴趣的:(算法,数据结构)