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(); } }
相关文章推荐
- NYOJ 195 飞翔 LIS变形
- Vawio Sequence (NYOJ 763 LIS变形)
- Android fragment 使用Sharepreferences来获取值,更新界面
- 关于h3c Magic B1无线路由器设置
- Linux端JBOSS修改端口
- UITableView之LOL英雄展示
- ML基石_8_NoiseAndError
- 源码学习—— Demo解析Canvas绘图
- Excel数据的导入导出
- ubuntu 14.04无法进入unity
- #include< >和#include""的区别
- Textview超出尺寸用...来表示
- 项目、团队、感悟
- C语言中的关键字 extern
- Linux中的df命令【简单使用】
- 转-CoreText 使用教程
- 用dataGridView实现增删改查
- 详解Java的线程的优先级以及死锁
- 如何隐藏RibbonBar的QAT QuickAccessToolBar
- HTML5工具/网站推荐