• Codeforces Round #271 (Div. 2) E. Pillars 线段树优化dp


    E. Pillars
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Marmot found a row with n pillars. The i-th pillar has the height of hi meters. Starting from one pillar i1, Marmot wants to jump on the pillars i2, ..., ik. (1 ≤ i1 < i2 < ... < ik ≤ n). From a pillar i Marmot can jump on a pillar j only if i < j and |hi - hj| ≥ d, where |x| is the absolute value of the number x.

    Now Marmot is asking you find out a jump sequence with maximal length and print it.

    Input

    The first line contains two integers n and d (1 ≤ n ≤ 105, 0 ≤ d ≤ 109).

    The second line contains n numbers h1, h2, ..., hn (1 ≤ hi ≤ 1015).

    Output

    The first line should contain one integer k, the maximal length of a jump sequence.

    The second line should contain k integers i1, i2, ..., ik (1 ≤ i1 < i2 < ... < ik ≤ n), representing the pillars' indices from the maximal length jump sequence.

    If there is more than one maximal length jump sequence, print any.

    Examples
    input
    5 2
    1 3 6 7 4
    output
    4
    1 2 3 5
    input
    10 3
    2 1 3 6 9 11 7 3 20 18
    output
    6
    1 4 6 7 8 9
    Note

    In the first example Marmot chooses the pillars 1, 2, 3, 5 with the heights 1, 3, 6, 4. Another jump sequence of length 4 is 1, 2, 4, 5.

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-8
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=2e5+10,M=2e6+10,inf=1e9+10,mod=1e9+7;
    const LL INF=1e18+10;
    
    struct SGT
    {
        int maxx[N<<2];
        void build(int l,int r,int pos)
        {
            memset(maxx,0,sizeof(maxx));
        }
        void update(int p,int c,int l,int r,int pos)
        {
            if(l==r)
            {
                maxx[pos]=c;
                return;
            }
            int mid=(l+r)>>1;
            if(p<=mid)update(p,c,l,mid,pos<<1);
            else update(p,c,mid+1,r,pos<<1|1);
            maxx[pos]=max(maxx[pos<<1],maxx[pos<<1|1]);
        }
        int query(int L,int R,int l,int r,int pos)
        {
            if(L<=l&&r<=R)return maxx[pos];
            int mid=(l+r)>>1;
            int ans=0;
            if(L<=mid)ans=max(ans,query(L,R,l,mid,pos<<1));
            if(R>mid)ans=max(ans,query(L,R,mid+1,r,pos<<1|1));
            return ans;
        }
    }tree;
    LL a[N],b[N];
    int n;
    LL k;
    int big(LL x)
    {
        int pos=lower_bound(b,b+2+n,x)-b;
        return pos;
    }
    int low(LL x)
    {
        int pos=upper_bound(b,b+2+n,x)-b-1;
        return pos;
    }
    int dp[N];
    vector<int>ans;
    int main()
    {
        scanf("%d%lld",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        b[n+1]=INF;
        b[0]=-INF;
        for(int i=1;i<=n;i++)
        {
            LL pre=a[i]-k;
            LL nex=a[i]+k;
            int pos1=low(pre);
            int pos2=big(nex);
            //cout<<pre<<" "<<nex<<" "<<pos1<<" "<<pos2<<endl;
            int maxx=0;
            if(pos1>=1)maxx=max(maxx,tree.query(1,pos1,1,n,1));
            if(pos2<=n)maxx=max(maxx,tree.query(pos2,n,1,n,1));
            dp[i]=maxx+1;
            tree.update(low(a[i]),maxx+1,1,n,1);
        }
        int maxx=0,pre=-1;
        for(int i=1;i<=n;i++)
        {
            if(dp[i]>maxx)
            {
                maxx=dp[i];
                pre=i;
            }
        }
        ans.push_back(pre);
        for(int i=pre-1;i>=1;i--)
        {
            if(abs(a[i]-a[pre])>=k&&dp[pre]==dp[i]+1)
            {
                pre=i;
                ans.push_back(pre);
            }
        }
        printf("%d
    ",maxx);
        for(int i=maxx-1;i>=0;i--)
            printf("%d ",ans[i]);
        return 0;
    }
  • 相关阅读:
    @media screen针对不同移动设备-响应式设计
    闭包的一些例子
    es6 新关键字const
    es6 新关键字let
    Unity 多屏(分屏)显示,Muti_Display
    小米手机常用操作
    Charles使用笔记
    AKKA学习笔记
    Gatling-Session
    Scala学习笔记-6-其他
  • 原文地址:https://www.cnblogs.com/jhz033/p/7258699.html
Copyright © 2020-2023  润新知