zoukankan      html  css  js  c++  java
  • HDU-4521 小明系列问题――小明序列(线段树)

    题目大意:求LIS,但是要求LIS中相邻的两个元素之间的距离要大于d。

    题目分析:线段树。节点(l,r)保存信息为LIS的最后一个元素落在[l,r]之间的最大长度。从第d+2个元素开始查询更新操作,但要在更新第i-d+1个元素信息之后。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<vector>
    # include<list>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=100000;
    
    int dp[N+5];
    int val[N+5];
    int tr[N*4+5];
    
    void build(int rt,int l,int r)
    {
    	tr[rt]=0;
    	if(l!=r){
    		int mid=l+(r-l)/2;
    		build(rt<<1,l,mid);
    		build(rt<<1|1,mid+1,r);
    	}
    }
    
    void update(int rt,int l,int r,int p,int v)
    {
    	if(l==r)
    		tr[rt]=max(tr[rt],v);
    	else{
    		int mid=l+(r-l)/2;
    		if(p<=mid) update(rt<<1,l,mid,p,v);
    		else update(rt<<1|1,mid+1,r,p,v);
    		tr[rt]=max(tr[rt<<1],tr[rt<<1|1]);
    	}
    }
    
    int query(int rt,int l,int r,int L,int R)
    {
    	if(L<=l&&r<=R)
    		return tr[rt];
    	int mid=l+(r-l)/2;
    	if(R<=mid) return query(rt<<1,l,mid,L,R);
    	if(L>mid) return query(rt<<1|1,mid+1,r,L,R);
    	return max(query(rt<<1,l,mid,l,mid),query(rt<<1|1,mid+1,r,mid+1,R));
    }
    
    int main()
    {
    	int n,d;
    	while(~scanf("%d%d",&n,&d))
    	{
    		int ans=1;
    		build(1,0,N);
    		for(int i=0;i<n;++i){
    			scanf("%d",val+i);
    			if(i>=d+1)
    				update(1,0,N,val[i-d-1],dp[i-d-1]);
    			if(val[i]>0)
    				dp[i]=query(1,0,N,0,val[i]-1)+1;
    			else dp[i]=1;
    			ans=max(ans,dp[i]);
    			
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    免登陆 安全密钥验证
    第五节
    selinux
    scp
    Linux网卡绑定
    HDFS
    搭建软件仓库
    命名空间“System.Web”中不存在类型或命名空间名称“Optimization”(是否缺少程序集引用?)
    delphi利用指针,结构或component存储数据表数据
    Delphi中的ObjectList简单用法一则
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5510096.html
Copyright © 2011-2022 走看看