Codeforces Round #271 (Div. 2)E. Pillars(dp+线段树优化)
2014-10-08 21:28
381 查看
题意:给定一个序列,求符合|ai-ai+1|>d的最长序列,并输出其一。
最长不下降序列的变形。最长不下降序列的nlogn算法实际上就是查询之前dp值最大的符合条件的最小元素。
因为不再维持单调性,所以在区间查询时不能用二分,而改用线段树进行区间查询。线段树维护的是以高度为区间的区间内dp值最大的元素。
复杂度依然为nlogn。
最长不下降序列的变形。最长不下降序列的nlogn算法实际上就是查询之前dp值最大的符合条件的最小元素。
因为不再维持单调性,所以在区间查询时不能用二分,而改用线段树进行区间查询。线段树维护的是以高度为区间的区间内dp值最大的元素。
复杂度依然为nlogn。
#include<stdio.h> #include<map> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define MAX(a,b) a>b?a:b #define MAXM 1000000000000000 #define INF 100000 #define MAXN 100010 #define lson 2*o,l,m #define rson 2*o+1,m+1,r map<int,int>mp; __int64 h[MAXN],a[MAXN],tree[MAXN*4],dp[MAXN],pre[MAXN]; int node[MAXN]; int n,d; int z=0; void discrete() { sort(a+1,a+n+1); } void init_tree() { memset(tree,0,sizeof(tree)); } int Query(int o,int l,int r,int i,int j,int &id) { if(j<i)return 0; if(i<=l&&j>=r){ if(z<tree[o])id=mp[o],z=tree[o]; return tree[o]; } if(l==r)return 0; if(i>r||j<l)return 0; int m=(l+r)>>1; int num1=Query(lson,i,j,id); int num2=Query(rson,i,j,id); return MAX(num1,num2); } void insert(int o,int l,int r,int pos,int data,int i){ if(l>pos||r<pos)return; if(l==r&&l==pos){ if(tree[o]<data)mp[o]=i; tree[o]=MAX(data,tree[o]); return; } if(l==r)return; int m=(l+r)>>1; insert(lson,pos,data,i); insert(rson,pos,data,i); if(tree[2*o]<tree[2*o+1])mp[o]=mp[2*o+1]; else mp[o]=mp[2*o]; tree[o]=MAX(tree[2*o],tree[2*o+1]); } void out(int x) { if(dp[x]==1){ cout<<x<<" "; return; } out(pre[x]); cout<<x<<" "; } void DP() { init_tree(); int max=0,temp=-1; for(int i=1;i<=n;i++){//对于每一个h[i] int x=lower_bound(a,a+n+2,h[i]-d)-a; if(a[x]!=h[i]-d)x--; int y=lower_bound(a,a+n+2,h[i]+d)-a; int id1=-1,id2=-1,id3=-1;z=-1; int len1=Query(1,1,n,1,x,id1); z=-1; int len2=Query(1,1,n,y,n,id2); if(len1<len2)id3=id2; else id3=id1; int ans=MAX(len1,len2); dp[i]=ans+1; if(max<dp[i]){ max=dp[i]; temp=i; } pre[i]=id3; int id=lower_bound(a+1,a+n+1,h[i])-a; insert(1,1,n,id,dp[i],i); } cout<<dp[temp]<<endl; out(pre[temp]); cout<<temp<<endl; } int main() { cin>>n>>d; a[0]=-MAXM; for(int i=1;i<=n;i++) { cin>>h[i]; a[i]=h[i]; } a[n+1]=MAXM; discrete(); DP(); return 0; }
相关文章推荐
- Codeforces Round #271 (Div. 2) E. Pillars 线段树优化dp
- Codeforces Round #271 (Div. 2) E. Pillars(线段树优化DP)
- Codeforces Round #271 (Div. 2) E Pillars(dp+线段树优化)
- Codeforces Round #271 (Div. 2) E. Pillars 线段树优化dp
- Codeforces Round #278 (Div. 2) D. Strip 线段树优化dp
- Codeforces #257 div2 E DZY Loves Colors 线段树优化
- Codeforces Round #426 (Div. 2) D. The Bakery 线段树优化DP
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
- CodeForces 833B The Bakery(dp+线段树优化)
- 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)
- 环中环 纪中1347 dp+线段树优化 玄学
- zoj 3349 Special Subsequence(dp+线段树优化)
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
- 【Codeforces Round 271 (Div 2)E】【离散化线段树】Pillars 最长连续序列使得序列相邻的数差值至少为k
- 字符串q次操作将(l,r)内的字符升序或降序排列 计数排序 + 线段树优化 Codeforces div2 558E A Simple Task
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
- Codeforces Round #426 (Div. 2) D 线段树优化dp
- Acdream 1126 Beautiful People(最长上升子序列,dp+线段树优化)
- Codeforces Round #318(Div. 1) 573 D. Bear and Cavalry【dp+矩阵+线段树优化】