18.10.9 不好做的最长上升子序列(nlogn树状数组解LIS)
Posted yalphait
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18.10.9 不好做的最长上升子序列(nlogn树状数组解LIS)相关的知识,希望对你有一定的参考价值。
描述
一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
输入
输入的第一行是序列的长度N (1 <= N <= 300000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到100000000之间。输出最长上升子序列的长度。
样例输入
7
1 7 3 5 9 4 8
样例输出
4
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 #include <stack> 5 #include <string> 6 #include <math.h> 7 #include <queue> 8 #include <stdio.h> 9 #include <string.h> 10 #include <vector> 11 12 #define lowbit(x) x&(-x) 13 14 using namespace std; 15 16 struct node { 17 int pos,value; 18 bool operator<(node a) { 19 if (value == a.value) 20 return pos > a.pos; 21 return value < a.value; 22 } 23 }; 24 25 const int maxn = 300005; 26 node n[maxn]; 27 int N,c[maxn]; 28 29 int query(int pos) { 30 int res = 0; 31 while (pos > 0) { 32 res = max(c[pos], res); 33 pos -= lowbit(pos); 34 } 35 return res; 36 } 37 38 void change(int pos,int len) { 39 while (pos <= N) { 40 c[pos] = max(c[pos], len); 41 pos += lowbit(pos); 42 } 43 } 44 45 int getmax() { 46 int s = N,res=0; 47 while (s > 0) { 48 res = max(res, c[s]); 49 s -= lowbit(s); 50 } 51 return res; 52 } 53 54 void process() { 55 for (int i = 1; i <= N; i++) { 56 int lis; 57 lis = query(n[i].pos) + 1; 58 change(n[i].pos, lis); 59 } 60 printf("%d ", getmax()); 61 } 62 63 64 int main() 65 { 66 scanf("%d", &N); 67 for (int i = 1; i <= N; i++) { 68 int val; 69 scanf("%d", &val); 70 n[i].pos = i, n[i].value = val; 71 } 72 sort(n + 1, n+N+1); 73 process(); 74 return 0; 75 }
我很好奇他们是怎么发现数据的范围一开始是错的??
课上睡着了没听到这题,看了PPT做的
以上是关于18.10.9 不好做的最长上升子序列(nlogn树状数组解LIS)的主要内容,如果未能解决你的问题,请参考以下文章