2018 计蒜客初 赛淘宝的推荐系统+TSL序列(dp+线段树优化)

描述

TSL序列的定义是满足|ai−ai−1|≤d,(0<i≤|a|)的序列。现在给你一个有n个元素的序列,求出这个序列的最长TSL子序列的长度。

输入

有多组测试数据,(数据组数≤20)。对于每组数据,第一行有两个整数n,d如题目所述。第二行有n个数a1,a2,…,an,中间以空格分割。
1≤n≤105
0≤d≤108
0≤ai≤108

输出

对于每组测试数据,输出一个整数表示该序列的最长TSL子序列的长度。

样例输入1

5 2
1 4 3 6 5
5 0
1 2 3 4 5

样例输出1

3
1

思路:计蒜客之道的d取值为d<100,所以直接枚举优化就OK了,但是这题d<10^18所以,无法枚举优化,所以考虑离散化后用线段树来查最值,思想是一样的,只不过多了一个离散化。

代码:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
#define Lson l,m,rt<<1
#define Rson m+1,r,rt<<1|1
int n;
int a[maxn];
int b[maxn];
struct Tree
{
    int l,r,Max;
}tree[maxn];
void push_up(int rt)
{
    tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
}
void Build(int l,int r,int rt)
{
    tree[rt].l=l,tree[rt].r=l;
    tree[rt].Max=0;
    if(l==r) return;
    int m=(l+r)>>1;
    Build(Lson);
    Build(Rson);
}
void updata(int pos,int v,int l,int r,int rt)
{
    if(l==r)
    {
        tree[rt].Max=max(tree[rt].Max,v);
        return;
    }
    int m=(l+r)>>1;
    if(pos>m) updata(pos,v,Rson);
    else updata(pos,v,Lson);
    push_up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        return tree[rt].Max;
    }
    int m=(l+r)>>1;
    int ans1=0,ans2=0;
    if(L<=m) ans1=query(L,R,Lson);
    if(R>m) ans2=query(L,R,Rson);
    return max(ans1,ans2);
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int T;
    cin>>T;
    while(T--)
    {
        int d;
        scanf("%d%d",&n,&d);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b,b+n);
        int tot=unique(b+1,b+1+n)-b;
        Build(1,tot,1);
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int l=lower_bound(b,b+tot,a[i]-d)-b+1;//线段树从1开始,所以左移一格
            int r=upper_bound(b,b+tot,a[i]+d)-b;//同理
            int tmp=query(l,r,1,tot,1);
            ans=max(ans,tmp+1);
            int pos=lower_bound(b,b+tot,a[i])-b+1;
            updata(pos,tmp+1,1,tot,1);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/82080730
今日推荐