您的位置:首页 > 其它

hdu 5489 Removed Interval LIS变形

2015-09-29 16:04 344 查看
//	hdu 5489 Removed Interval LIS变形
//
//	解题思路:
//		f[i]为以a[i]为结尾的LIS
//		g[i]为以a[i]为开头的LIS
//		对于截掉一段L而言,我们可以设将i位置前的L去除,但是
//		保留i的这样的状态.这样dp[i] = max(dp[j]) (1<=j<=i-L) + g[i]
//		再对dp[i]选出一个max就是最后的答案啦.
//		关键在于如何找到最大的dp[j].
//		我们先将高度映射到线段树上,当然需要离散化一下,对于一个a[i].
//		我们查找(1,a[i]-1)区间里面的最大的dp[j]就行了.而对于插入的话
//		插入对于一个a[i-L],我们插入f[i-L]的值.
//		这个方法的技巧就在于我们多加一个元素INF放在a[i]的末尾,这样就可以
//		保证所有连续的L的序列都考虑到了.所以正确性是肯定的.
//
//	感悟:
//
//		比赛的时候,是观摩神犇学弟一起搞出来的,用的三棵线段树.确实搞出来了
//		当时十分激动,AC的感觉十分兴奋,太爽啦!继续加油吧~~~FIGHTING!!!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(x,a,b,c) for (int x = a; x <= b; x += c)
#define pre(x,a,b,c) for (int x = a; x >= b; x -= c)
#define cls(x,a) memset(x,a,sizeof(x))
using namespace std;
const int MAX_N = 1e5 + 8;
const int INF = 0x7f7f7f7f;
int N,L;
int a[MAX_N];
int tem[MAX_N];
int f[MAX_N];
int g[MAX_N];
int h[MAX_N];

struct IntervalTree{

#define lson(ro) (ro<<1)
#define rson(ro) (ro<<1|1)
int maxv[MAX_N<<2];
int ql,qr,v;

inline void push_up(int ro){
maxv[ro] = max(maxv[lson(ro)],maxv[rson(ro)]);
}

void build(int ro,int L,int R){
maxv[ro] = 0;
if (L == R){
return ;
}
int M = (L + R) >> 1;
build(lson(ro),L,M);
build(rson(ro),M+1,R);
}

void update(int ro,int L,int R){
if (L == R){
maxv[ro] = max(maxv[ro],v);
return ;
}

int M = (L + R) >> 1;
if (ql <= M)	update(lson(ro),L,M);
else	update(rson(ro),M+1,R);
push_up(ro);

}

int query(int ro,int L,int R){
if (ql <= L && R <= qr){
return maxv[ro];
}

int M = (L + R) >> 1;
int ans = 0;
if (ql <= M)	ans = max(ans,query(lson(ro),L,M));
if (M < qr)		ans = max(ans,query(rson(ro),M+1,R));
return ans;
}

}it;

void input(){
scanf("%d%d",&N,&L);
it.build(1,1,N);
rep(i,1,N,1){
scanf("%d",&a[i]);
tem[i] = a[i];
}
sort(tem+1,tem+N+1);
int siz = unique(tem+1,tem+N+1) - tem - 1;
cls(h,0x7f);

rep(i,1,N,1){
int k = lower_bound(h+1,h+N+1,a[i]) - h;
f[i] = k;
h[k] = a[i];
}

cls(h,0x7f);

pre(i,N,1,1){
int k = lower_bound(h+1,h+N+1,-a[i]) - h;
g[i] = k;
h[k] = -a[i];
}

int ans = 0;
a[N+1] = INF;
g[N+1] = 0;
rep(i,L+1,N+1,1){
int k = lower_bound(tem+1,tem+siz+1,a[i]) - tem;
it.ql = 1;
it.qr = (k >1 ? k-1 : 1);
ans = max(ans,it.query(1,1,N)+g[i]);
k = lower_bound(tem+1,tem+siz+1,a[i-L]) - tem;
it.ql = k;
it.v = f[i-L];
if (i <= N)
it.update(1,1,N);
}

printf("%d\n",ans);

}

int main(){
int t;
int kase = 1;
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%d",&t);
while(t--){
printf("Case #%d: ",kase++);
input();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息