ZOJ 3349 Special Subsequence

2791 단어
세그먼트 트리 최적화 DP...
Special Subsequence
Time Limit: 5000MS
 
Memory Limit: 32768KB
 
64bit IO Format: %lld & %llu
[Submit]   [Go Back]   [Status]  
Description
There a sequence S with n integers , and A is a special subsequence that satisfies |Ai-Ai-1| <= d ( 0 Now your task is to find the longest special subsequence of a certain sequence S
Input
There are no more than 15 cases , process till the end-of-file
The first line of each case contains two integer n and d ( 1<=n<=100000 , 0<=d<=100000000) as in the description.
The second line contains exact n integers , which consist the sequnece S .Each integer is in the range [0,100000000] .There is blank between each integer.
There is a blank line between two cases
Output
For each case , print the maximum length of special subsequence you can get.
Sample Input
5 2
1 4 3 6 5

5 0
1 2 3 4 5

Sample Output
3
1
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn=101000;

int n,d,a[maxn],b[maxn],t,dp[maxn];

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int tree[maxn<<2];

void push_up(int l,int r,int rt)
{
    tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}

void build(int l,int r,int rt)
{
    if(l==r)
    {
        tree[rt]=0;
        return ;
    }
    int m=(l+r)>>1;
    build(lson); build(rson);
    push_up(l,r,rt);
}

int query(int l,int r,int rt,int L,int R)
{
    if(L<=l&&r<=R)
    {
        return tree[rt];
    }
    int m=(l+r)>>1;
    int ret=-1;
    if(L<=m) ret=max(ret,query(lson,L,R));
    if(R>m) ret=max(ret,query(rson,L,R));
    return ret;
}

void update(int l,int r,int rt,int P,int V)
{
    if(l==r)
    {
        tree[rt]=V;
        return ;
    }

    int m=(l+r)>>1;

    if(P<=m) update(lson,P,V);
    else update(rson,P,V);

    push_up(l,r,rt);
}

int main()
{
while(scanf("%d%d",&n,&d)!=EOF)
{
    for(int i=1;i<=n;i++)
    {
        scanf("%d",a+i);
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    int t=unique(b+1,b+n+1)-b-1;
    memset(dp,0,sizeof(dp));
    dp[1]=1;
    build(1,n,1);

    for(int i=1;i<=n;i++)
    {
        int rt=lower_bound(b+1,b+t+1,a[i])-b;
        int l=lower_bound(b+1,b+t+1,a[i]-d)-b;
        int r=upper_bound(b+1,b+t+1,a[i]+d)-(b+1);
        dp[i]=query(1,n,1,l,r)+1;
        update(1,n,1,rt,dp[i]);
    }

    int ans=-1;
    for(int i=1;i<=n;i++)
        ans=max(ans,dp[i]);

    printf("%d
",ans); } return 0; }

좋은 웹페이지 즐겨찾기