nlogn求LIS(树状数组)
之前一直是用二分
但是因为比较难理解,写的时候也容易忘记怎么写。
今天比赛讲评的时候讲了一种用树状数组求LIS的方法
(1)好理解,自然也好写(但代码量比二分的大)
(2)扩展性强。这个解法顺带求出以i为结尾的LIS,而很多题要用到这个数组来做
而二分的做法求得是当前长度下的最小值,不容易拓展。
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; const int MAXN = 1e3 + ;
int a[MAXN], b[MAXN], n, m, ans;
int dp[MAXN], f[MAXN]; inline int lowbit(int x) { return x & (-x); } void motify(int x, int p)
{
for(; x <= m; x += lowbit(x))
f[x] = max(f[x], p);
} int get_max(int x)
{
int res = ;
for(; x; x -= lowbit(x))
res = max(res, f[x]);
return res;
} int main()
{
scanf("%d", &n);
_for(i, , n) scanf("%d", &a[i]), b[i] = a[i]; sort(b + , b + n + );
m = unique(b + , b + n + ) - b - ;
_for(i, , n) a[i] = lower_bound(b + , b + m + , a[i]) - b; int ans = ;
_for(i, , n)
{
dp[i] = get_max(a[i] - ) + ;
ans = max(ans, dp[i]);
motify(a[i], dp[i]);
}
printf("%d\n", ans);
return ;
}
具体怎么做呢
n方的算法有一步去枚举之前所有的元素比较耗时间
可以用树状数组优化这一步,树状数组维护区间最大值
把元素的值当作下标,dp值作为值
a[i]表示当前值,dp[i]表示以i为结尾最长不下降子序列的长度
则 dp[i] = get_max(a[i]) + 1
也就是说,在小于等于当前值a[i]中,最大的dp值+1就是当前的答案
不过这里有个细节,怎么区分最长不下降还是最长上升?
如果你对原理理解透彻的话,这个问题其实很容易解决,你可以停下来自己推一下,检验一下自己理解了没有
如果是最长不下降的话,dp[i] = get_max(a[i]) + 1
如果最长上升的话, dp[i] = get_max(a[i]-1) + 1
最后注意要离散化一下
以下是最长上升子序列的模板
nlogn求LIS(树状数组)的更多相关文章
- 【Codeforces】Gym 101156E Longest Increasing Subsequences LIS+树状数组
题意 给定$n$个数,求最长上升子序列的方案数 根据数据范围要求是$O(n\log n)$ 朴素的dp方程式$f_i=max(f_j+1),a_i>a_j$,所以记方案数为$v_i$,则$v_i ...
- Codeforces 960F Pathwalks ( LIS && 树状数组 )
题意 : 给出若干个边,每条边按照给出的顺序编号,问你找到一条最长的边权以及边的编号同时严格升序的一条路径,要使得这条路径包含的边尽可能多,最后输出边的条数 分析 : 这题和 LIS 很相似,不同的 ...
- HDU - 5542 The Battle of Chibi(LIS+树状数组优化)
The Battle of Chibi Cao Cao made up a big army and was going to invade the whole South China. Yu Zho ...
- BZOJ-3881:Divljak (AC自动机+DFS序+树链求并+树状数组)
Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. “2 x” ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- 题解 P3374 【【模板】树状数组 1】
恩,这是AC的第一道树状数组呢. 本蒟蒻以前遇到RMQ问题一般都用线段树或ST表,可惜ST表不支持在线修改,而线段树代码量又太大. 如今终于找到了折中方案:树状数组!!!!代码量小,还支持修改! 树状 ...
- (新人的第一篇博客)树状数组中lowbit(i)=i&(-i) 的简单文字证明
第一次写博好激动o(≧v≦)o~~初一狗语无伦次还请多多指教 先了解树状数组http://blog.csdn.net/int64ago/article/details/7429868感觉这个前辈写 ...
- HDU2852【树状数组+二分】
额..有点遗忘了树状数组特性了..印象中一直是前缀和,然后一定要记住树状数组是把给出的值(值太大可能可以离散化)也就是点到了区间,然后这个点存的值就是由自己来定了. 题意: 百度. 思路: 树状数组是 ...
- [BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)
传送门 看到这个题有个很暴力的想法, 可以每一个时间点都建一颗主席树,主席树上叶子节点 i 表示优先级为 i 的任务有多少个. 当 x 到 y 有个优先级为 k 的任务时,循环 x 到 y 的每个点, ...
随机推荐
- bzoj3663
几何+lis 很巧妙.直接做很困难,那么我们转化一下,把每个点能看见的圆弧画出来.只有这些圆弧相交时才满足条件. 那么也就是找出圆上尽量多两两相交的区间. 所以我们先按左端点极角排序,然后固定一个必须 ...
- opensStack
- 直接使用FileSystem以标准输出格式显示hadoop文件系统中的文件
package com.yoyosys.cebbank.bdap.service.mr; import java.io.IOException; import java.io.InputStream; ...
- PCB SQL SERVER 字段模糊匹配个数 实现方法
今天工程系统给到加投加投组件的数据规则修改,遇到需将一个字段模糊匹配的个数统计 这类需求要平时应该很少遇到了,这里将此方法分享出来, 一.需求如下 例子:itempara字段中的内容是: IVH板 铜 ...
- http通讯基础
1 . 一个网页包括 JS CSS Html 2 . 状态码:200 正常 302 临时重定向 (类似呼叫转移) 304 未修改,客户端缓存的信息是最新的,无需到服务器重新获取 403 ...
- python抢票开发——设备预约助手实现
女朋友是药学院的,做实验时需要在特定的网站上进行设备预约,由于预约人数过多,从而导致从浏览器登录不进去或者登录进去预约失败等情况,所以我用python帮她写了一个抢位助手,让程序自动去进行位置预定,实 ...
- 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)
上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...
- 【知识总结】快速傅里叶变换(FFT)
这可能是我第五次学FFT了--菜哭qwq 先给出一些个人认为非常优秀的参考资料: 一小时学会快速傅里叶变换(Fast Fourier Transform) - 知乎 小学生都能看懂的FFT!!! - ...
- tomcat解决 java.lang.IllegalArgumentException: Request header is too large
tomcat运行项目时,有一个请求过去后,后台报这样的错java.lang.IllegalArgumentException: Request header is too large 原因:请求头超过 ...
- 题解报告:hdu 1564 Play a game(找规律博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1564 Problem Description New Year is Coming! ailyanlu ...