HDU-4521 小明系列问题――小明序列(线段树)
2016-05-19 20:46
302 查看
题目大意:求LIS,但是要求LIS中相邻的两个元素之间的距离要大于d。
题目分析:线段树。节点(l,r)保存信息为LIS的最后一个元素落在[l,r]之间的最大长度。从第d+2个元素开始查询更新操作,但要在更新第i-d+1个元素信息之后。
代码如下:
题目分析:线段树。节点(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\n",ans); } return 0; }
相关文章推荐
- 【C程序设计语言(第二版)学习】单词计数 方法
- 第十三周周记
- 第12周表格
- 并查集+最大流-HDU-3038-Marriage Match II
- mybatis异常
- Iterable(迭代器)的用法
- zend studio 12汉化和破解
- stl中的tuple(tie)
- nginx 跨域配置
- Android中的通知Notification
- JAVA 大整数类
- jquery动画-animate()
- Multiple dex files define Landroid/support/annotation/AnimRes
- the server ssl certificate failed to verify
- U盘为什么还有剩余空间,但却提示说空间不够
- 集合
- play-maven脚本
- Leetcode 345. Reverse Vowels of a String
- 第十二周周记
- 第11周表格