题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551

题意:

给出一段序列, 删除其中一段连续的子序列(或者不删), 使得剩下的序列的最长上升连续子序列最大。

题解:

1.对于要删除的的子序列而言,要么夹在答案序列中间,要么在外面(删与不删对答案都没影响)。所以总体而言,答案序列被分成左右两半。

2.用SL[i]记录从左边起以a[i]为结尾的最长上升连续子序列的长度, SR记录从右边起以a[i]为开始的最长上升连续子序列的长度。

3.枚举SR[i],用线段树找出最大的SL[x](x的下标小于i),即SL[x]和SR[x]构成一段完整的序列, 期间一直更新线段树。

学习之处:

1.线段树/树状数组的动态使用,即边查询边更新。

类似的题: http://blog.csdn.net/DOLFAMINGO/article/details/65643894

2.RMQ/线段树/树状数组的静态使用,即build()之后值进行查询操作。

相关的题:http://blog.csdn.net/DOLFAMINGO/article/details/68953809       http://blog.csdn.net/dolfamingo/article/details/70306529

线段树:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[maxn], SL[maxn], SR[maxn], MAX[maxn<<];
int n; void update(int rt, int l, int r, int pos)
{
if(l==r)
{
MAX[rt] = max(MAX[rt], SL[pos]);
return;
} int mid = (l+r)>>;
if(a[pos]<=mid) update(rt*, l, mid, pos);
else update(rt*+ ,mid+, r, pos); MAX[rt] = max(MAX[rt*], MAX[rt*+]);
} int query(int rt, int l, int r, int x, int y)
{
if(x<=l && y>= r)
return MAX[rt]; int mid = (l+r)>>, ret = ;
if(x<=mid) ret = max(ret, query(rt*, l, mid, x, y));
if(y>=mid+) ret = max(ret, query(rt*+, mid+, r, x, y));
return ret;
} void solve()
{
for(int i = ; i<=n; i++)
scanf("%d",&a[i]); SL[] = SR[n] = ;
for(int i = ; i<=n; i++)
SL[i] = (a[i]>a[i-]?SL[i-]+:);
for(int i = n-; i>; i--)
SR[i] = (a[i]<a[i+]?SR[i+]+:); int ans = ;
for(int i = ; i<=n; i++)
{
int tmp = ;
if(a[i]>) tmp = query(, , , , a[i]-); ans = max(ans,SR[i]+tmp);
update(, , , i); }
printf("%d\n",ans);
} int main()
{
while(scanf("%d",&n)!=EOF)
{
ms(SL,);
ms(SR,);
ms(MAX,);
solve();
}
}

树状数组:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; int a[maxn], SL[maxn], SR[maxn], c[maxn];
int n; int lowbit(int x)
{
return x&(-x);
} void add(int x, int d)
{
while(x<maxn)
{
c[x] = max(c[x],d);
x += lowbit(x);
}
} int sumc(int x)
{
int s = ;
while(x>)
{
s = max(s,c[x]);
x -= lowbit(x);
}
return s;
} void solve()
{
for(int i = ; i<=n; i++)
scanf("%d",&a[i]); SL[] = SR[n] = ;
for(int i = ; i<=n; i++)
SL[i] = (a[i]>a[i-]?SL[i-]+:);
for(int i = n-; i>; i--)
SR[i] = (a[i]<a[i+]?SR[i+]+:); int ans = ;
for(int i = ; i<=n; i++)
{
int tmp = ;
if(a[i]>) tmp = sumc(a[i]-); ans = max(ans,SR[i]+tmp);
add(a[i],SL[i]); }
printf("%d\n",ans);
} int main()
{
while(scanf("%d",&n)!=EOF)
{
ms(SL,);
ms(SR,);
ms(c,);
solve();
}
}

CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和的更多相关文章

  1. CSU 1551 Longest Increasing Subsequence Again(树状数组 或者 LIS变形)

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551 升级版:Uva 1471 题意: 让你求删除一段连续的子序列之后的LIS. 题 ...

  2. csu 1551: Longest Increasing Subsequence Again BIT + 思维

    预处理last[i]表示以第i个开始,的合法后缀. pre[i]表示以第i个结尾,的合法前缀. 那么每一个数a[i],肯定是一个合法后缀last[i] + 一个合法前缀,那么合法前缀的数字要小于a[i ...

  3. CSUOJ 1551 Longest Increasing Subsequence Again

    1551: Longest Increasing Subsequence Again Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 75  Solved ...

  4. FZU2013 A short problem —— 线段树/树状数组 + 前缀和

    题目链接:https://vjudge.net/problem/FZU-2013  Problem 2013 A short problem Accept: 356    Submit: 1083Ti ...

  5. [tem]Longest Increasing Subsequence(LIS)

    Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...

  6. The Longest Increasing Subsequence (LIS)

    传送门 The task is to find the length of the longest subsequence in a given array of integers such that ...

  7. SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

    Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...

  8. Dynamic Programming | Set 3 (Longest Increasing Subsequence)

    在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 和 Dynamic Programming | Set 2 (Opti ...

  9. [LeetCode] Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

随机推荐

  1. rocketMq---------相关命令

    搭建就不详细说了,cent7.x的系统,openJdk8,maven3.x,gradle4.10.2, git 1.8.3.1 直接下载相关的二进制压缩包,解压即用,方便. 下面看常用的管理命令 ro ...

  2. G - Specialized Four-Digit Numbers(1.5.2)

    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...

  3. 南阳 oj 表达式求值 题目35 数据结构 NYO题目链接

     建议不会的看别人的代码自己在之上模拟一遍,仅仅要耐心模拟就会做出来 题目链接:http://acm.nyist.net/JudgeOnline/problem.php? pid=35 #incl ...

  4. CTP报单状态 OrderStatus全部状态

  5. sum-root-to-leaf-numbers——dfs

    Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number. ...

  6. Laravel 5.4建站06--API 认证系统 Passport

    介绍 在 Laravel 中,实现基于传统表单的登陆和授权已经非常简单,但是如何满足 API 场景下的授权需求呢?在 API 场景里通常通过令牌来实现用户授权,而非维护请求之间的 Session 状态 ...

  7. nvidia-docker_1.0.1-1_amd64.deb 百度云下载分享

    nvidia-docker_1.0.1-1_amd64.deb 链接: https://pan.baidu.com/s/1i5pHFNZ 密码: xjui

  8. 啥是Restful?

    在Web设计与开发中,经常会看到Restful这个概念.对HTTP没有深入了解的我看到这个,基本一带而过. 其实既然只是概念,理解其中的意思就OK. Restful 1. 一种Web设计/架构方式 2 ...

  9. java 连接mysql 和sql server2008代码

    这两天用java分别连接mysql和sql server2008代码.刚開始都是有错.如今找到了在 自己机器上成功连接的代码: 1. mysql Class.forName("com.mys ...

  10. 文件共享和使用 dup 函数创建新描述符的区别

    前言 文件共享是指同时打开一个文件 用 dup 函数能对指定文件描述符再创建一个新的描述符,且这个新的描述符和旧的描述符指向的是同一个文件. 这两种行为有什么区别呢?下面给出的两张文件系统的图形象的解 ...