您的位置:首页 > 其它

Codeforces Round #271 (Div. 2)E. Pillars(dp+线段树优化)

2014-10-08 21:28 381 查看
题意:给定一个序列,求符合|ai-ai+1|>d的最长序列,并输出其一。

最长不下降序列的变形。最长不下降序列的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: