hdu 5489 Removed Interval LIS变形

来源:互联网 发布:零售业数据定义 编辑:程序博客网 时间:2024/05/16 08:30
//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);elseupdate(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();}}

0 0
原创粉丝点击