CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和
题目链接: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 —— 线段树/树状数组 + 前缀和&后缀和的更多相关文章
- CSU 1551 Longest Increasing Subsequence Again(树状数组 或者 LIS变形)
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551 升级版:Uva 1471 题意: 让你求删除一段连续的子序列之后的LIS. 题 ...
- csu 1551: Longest Increasing Subsequence Again BIT + 思维
预处理last[i]表示以第i个开始,的合法后缀. pre[i]表示以第i个结尾,的合法前缀. 那么每一个数a[i],肯定是一个合法后缀last[i] + 一个合法前缀,那么合法前缀的数字要小于a[i ...
- CSUOJ 1551 Longest Increasing Subsequence Again
1551: Longest Increasing Subsequence Again Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 75 Solved ...
- FZU2013 A short problem —— 线段树/树状数组 + 前缀和
题目链接:https://vjudge.net/problem/FZU-2013 Problem 2013 A short problem Accept: 356 Submit: 1083Ti ...
- [tem]Longest Increasing Subsequence(LIS)
Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...
- The Longest Increasing Subsequence (LIS)
传送门 The task is to find the length of the longest subsequence in a given array of integers such that ...
- SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治
Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...
- Dynamic Programming | Set 3 (Longest Increasing Subsequence)
在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 和 Dynamic Programming | Set 2 (Opti ...
- [LeetCode] Longest Increasing Subsequence 最长递增子序列
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
随机推荐
- Jackson对泛型的序列化和反序列化方法汇总
说明:Jackson对于简单泛型是可以正常操作的,但是如果对于太过于复杂的泛型类有时会不成功.目前还在找着更合适的Json库.不过这一点在dotnet原生方案JavaScriptSerializer可 ...
- Java获取当前时间戳/时间戳转换
时间戳精度有两个概念:1是精确到秒,2是精确到毫秒. 要操作时间戳和时间戳转换为时间一般对应的对象就是Date,而Date各种转换离不开SimpleDateFormat: 如果是要获取时间指定的年月日 ...
- 【GitHub】给GitHub上的ReadMe.md文件中添加图片怎么做 、 gitHub创建文件夹
1.首先在github上的仓库上,创建一个空的文件夹,用于上传图片 上图看 要点击的按钮是创建新的文件,并不是创建新的文件夹,具体怎么?往下看 这个时候,下面的提交按钮才能提交 2.进入新创建的文件夹 ...
- 启动weblogic域不需要输入密码设置方法
分类: IT综合技术 一.问题描述与分析 部署完WEBLOGIC后,在每次启动时执行./startWebLogic.sh脚本时,都会停在输入用户名与密码这里,相当不方便.所以要做到启动过程不输 ...
- IOS开发退出应用程序的代码
IOS 开发中.我知道的两个退出程序的方法: 1. exit(0); 2. if([[UIApplication sharedApplication] respondsToSelector:@sele ...
- 彻底搞懂oracle的标量子查询
oracle标量子查询和自己定义函数有时用起来比較方便,并且开发者也常常使用.数据量小还无所谓.数据量大,往往存在性能问题. 下面測试帮助大家彻底搞懂标量子查询. SQL> create tab ...
- Odoo(OpenERP)开发实践:通过XML-RPC接口訪问Odoo数据库
Odoo(OpenERP)server支持通过XML-RPC接口訪问.操作数据库,基于此可实现与其它系统的交互与集成. 本文是使用Java通过XMLRPC接口操作Odoo数据库的简单演示样例.本例引用 ...
- Lightoj 1088 - Points in Segments 【二分】
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1088 题意: 有一维的n个点和q条线段.询问每条线段上的点有多少个. 思路:寻 ...
- idea2018注册方法
下面是具体的破解激活步骤: 1. 下载破解补丁文件,路径为:http://idea.lanyus.com/jar/JetbrainsCrack-2.7-release-str.jar 2.将补丁放在安 ...
- 宜信开源微服务任务调度平台(SIA-TASK)
背景 无论是互联网应用或者企业级应用,都充斥着大量的批处理任务.常常需要一些任务调度系统帮助开发者解决问题.随着微服务化架构的逐步演进,单体架构逐渐演变为分布式.微服务架构.在此的背景下,很多原先的任 ...