Codeforces Round #271 (Div. 2) E Pillars(dp+线段树优化)
2014-10-07 18:56
351 查看
题目要求abs(d[i]-d[j])>=d,也就是说只要a[j]<=a[i]-d或者a[i]+d<=a[j] ,也就是只要求1~a[i]-d即a[i]+d~max里最大的dp值,这就是一个线段树查询问题。建议先看一下本博客里面LIS线段树优化的文章。
下面是AC代码:
下面是AC代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define LL long long using namespace std; int dp[100005],pre[100005]; LL s[100005],a[100005]; int b[100005]; struct pi{ int le; int ri; int ma; }pp[400005]; void init(int tot,int l,int r){ pp[tot].ma=-1; pp[tot].le=l; pp[tot].ri=r; if(l==r) return ; init(2*tot,l,(l+r)/2); init(2*tot+1,(l+r)/2+1,r); } void merg(int tot,int p,int n){ if(pp[tot].le==pp[tot].ri){ if(pp[tot].ma==-1) pp[tot].ma=n; else{ if(dp[pp[tot].ma]<dp ){ pp[tot].ma=n; } } return ; } int mid=(pp[tot].le+pp[tot].ri)/2; if(p<=mid) merg(2*tot,p,n); else merg(2*tot+1,p,n); if(pp[2*tot].ma==-1) pp[tot].ma=pp[2*tot+1].ma; if(pp[2*tot+1].ma==-1) pp[tot].ma=pp[2*tot].ma; if(dp[pp[2*tot].ma]<dp[pp[2*tot+1].ma]) pp[tot].ma=pp[2*tot+1].ma; else pp[tot].ma=pp[2*tot].ma; } int query(int tot,int l,int r){ int x,y; if(l<=pp[tot].le&&r>=pp[tot].ri) return pp[tot].ma; int mid; mid=(pp[tot].le+pp[tot].ri)/2; x=-1; y=-1; if(l<=mid) x=query(2*tot,l,r); if(r>mid) y=query(2*tot+1,l,r); if(x==-1) return y; if(y==-1) return x; if(dp[x]<dp[y]) return y; return x; } int get(int n,LL k){ int le,ri,mid; le=1; ri=n; while(le<=ri){ mid=(le+ri)/2; if(s[mid]<k) le=mid+1; else ri=mid-1; } return le; } int main() { int i,j,n,m,p,k,d,x,y; LL a1,b1; cin>>n>>d; for(i=1;i<=n;i++){ cin>>a[i]; s[i]=a[i]; } sort(s+1,s+1+n); dp[0]=0; init(1,1,n); memset(pre,-1,sizeof(pre)); for(i=1;i<=n;i++){ if(i==1){ dp[1]=1; p=get(n,a[i]); merg(1,p,1); } else{ x=-1; y=-1; a1=a[i]-d; if(a1>0){ p=get(n,a1); if(p>n||s[p]!=a1) p--; } else p=0; if(p>0) x=query(1,1,p); b1=a[i]+d; p=get(n,b1); if(p<=n) y=query(1,p,n); if(x==-1&&y==-1) dp[i]=1; else{ if(x==-1){ dp[i]=dp[y]+1; pre[i]=y; } else if(y==-1){ dp[i]=dp[x]+1; pre[i]=x; } else{ if(dp[x]<dp[y]){ dp[i]=dp[y]+1; pre[i]=y; } else { dp[i]=dp[x]+1; pre[i]=x; } } } p=get(n,a[i]); merg(1,p,i); } } p=0; for(i=1;i<=n;i++){ if(dp[i]>p) p=dp[i]; } int tot; printf("%d\n",p); tot=0; for(i=1;i<=n;i++){ if(dp[i]==p){ b[tot++]=i; i=pre[i]; while(i!=-1){ b[tot++]=i; i=pre[i]; } break; } } for(i=tot-1;i>=0;i--) printf(" %d",b[i]); printf("\n"); }
相关文章推荐
- Codeforces Round #271 (Div. 2)E. Pillars(dp+线段树优化)
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
- 环中环 纪中1347 dp+线段树优化 玄学
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
- Codeforces Round #426 (Div. 2) D 线段树优化dp
- Codeforces Round #318(Div. 1) 573 D. Bear and Cavalry【dp+矩阵+线段树优化】
- Codeforces Round #271 (Div. 2) E. Pillars(线段树优化DP)
- Contest20140906 ProblemA dp+线段树优化
- HDU 5125 magic balls(dp+线段树优化)
- Codeforces Round #271 (Div. 2) E. Pillars 线段树优化dp
- bzoj1835 [ZJOI2010]base 基站选址(dp+线段树优化)
- ZOJ 3349 Special Subsequence(DP+线段树优化)
- #Poj1769#Minimizing maximizer(Dp+线段树优化)
- ZOJ 3349 Special Subsequence(DP+线段树优化)
- 字符串q次操作将(l,r)内的字符升序或降序排列 计数排序 + 线段树优化 Codeforces div2 558E A Simple Task
- HDU 4521 小明系列问题——小明序列【dp+线段树优化||最长递增序列】
- ZOJ 3349 Special Subsequence【dp+线段树优化】
- dp+线段树优化-hdu-3698-Let the light guide us
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(线段树+离散化优化DP)
- 1376 最长递增子序列的数量(dp+线段树优化)