Can you tell me how to find LIS in O(nlogn) time using Binary Indexed Trees? What about using Interval trees?
# | User | Rating |
---|---|---|
1 | tourist | 4009 |
2 | jiangly | 3823 |
3 | Benq | 3738 |
4 | Radewoosh | 3633 |
5 | jqdai0815 | 3620 |
6 | orzdevinwang | 3529 |
7 | ecnerwala | 3446 |
8 | Um_nik | 3396 |
9 | ksun48 | 3390 |
10 | gamegame | 3386 |
# | User | Contrib. |
---|---|---|
1 | cry | 167 |
2 | maomao90 | 163 |
2 | Um_nik | 163 |
4 | atcoder_official | 161 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 157 |
8 | TheScrasse | 154 |
9 | nor | 153 |
9 | Dominater069 | 153 |
Can you tell me how to find LIS in O(nlogn) time using Binary Indexed Trees? What about using Interval trees?
Name |
---|
in fenwıck tree(binary indexed tree) updating a single position and asking for query on intervals is well known algorithm. while increasing fenwick positions in sum queries , for max query you can update fenwick positions , but dont forget in max query with fenwick you can just get max of intevals begins form leftmost like this [1,i] and if you will change some point with less value this solution doesnt work. hope this helps:)
But what should you update particularly for LIS and what query you "call" to get the answer?
Well, if we calculate an array d[value] — the length of the LIS with the last element being value up to the current position in an original array, then to find the value d[currValue] we must search the maximum in prefix d[minValue;currValue–1]. And this is with BIT and segment tree. :]
Can you give a code example cuz i still dont understand in :(
You can look at my solution 4380966, I do exactly the same as gen had wrote.
using segment tree: 4386727
It's pretty simple. Let a[] be the given array, and d[] be the array defined earlier. Suppose we are at a[i]. What is the LIS that ends with a[i]? The element before the last should be less than a[i]. Let that element be value. Now at d[value] is the length of the LIS that ends with value. So we should update d[a[i]] with d[value] + 1, if it is greater than d[a[i]]. So we search for the maximum d[value] where value is less than a[i]. That is why we can use BIT and segment tree to calculate the maximum on a prefix d[minValue;a[i] - 1]. As you see in Alex_2oo8 and LashaBukhnikashvili implementations, the answer is the maximum of d[] values.
@gen : d[a[i]] should not be d[i] because we are at a[i] ? and you are saying that we have to search in this range d[minValue;a[i] - 1]. Wht is minValue here ? Kindly pls explain me .I know the nlogn algorithm for the same using binary search.
It should be d[a[i]] because we want to update the length of the LIS that ends with a[i], by the definition of array d[].
minValue is just the smallest value in array a[]. Typically it is simply 0.
well there is also one another solution with using same data structer , if we taking array elements in ascending order then using dp array like this
dp[i] = answer (i is some position 1 to N)
N is the number of elements at input , at any step there will be only less then current value at left that already updated. so we call max_query(1 , i-1), with this solution if maximum value of array elements is huge it works but yours doesnt :) , here is pseudo code :so if the a is this :
what should i do if i want to find the LIS?
maximum value of dp array is lis !!! :(
I think he meant the subsequence itself, not just the length -- you should create an additional array to store the backpointers.
int[] backpointers -- backpointers[i] = the index j < i where you continued off.
After the dp table is filled, find the index i which maximizes dp[i], then follow backpointers from there. This will give the reversed LIS.
oh sorry :) i misunderstood.
Thanks guys!!!
Excuse me for asking again but if you consider my solution what should I add to keep track of LIS elements. Sorry for disturbing you.
I understand how fenwick can be used to do max[first k els of array], but I have no idea how to recover the index 'i' such that the imaginary arr[i] = fenwick_max[0..i]. So.. idk
Other than personal choice/ease of coding, I think the more well-known dp[] approach is better not only because you can recover LIS easier, and also that particular fenwick approach is limited by the size of the values of the array -- If values extend to 10^9, it probably won't work.
Jk got it to work. Can't click the damn edit button on my other post because it's too squished, so I made a new post. http://pastebin.com/cHyeiTLk I only modified where you update dp[i], made use of tree[idx][2] to store the actual index to the input array that ends the sequence.
if values extend 10^9 you can compress them , so fenwick works:)
Thanks 1 more time
ikbal Can you elaborate on when should we use max in Fenwick? Maybe with an example!
https://mirror.codeforces.com/contest/340/submission/89817578
Hope this helps :)
It can be solved with dp using binary search, Here is tutorial.
I solved it like that
Without using trees:
Keep an array S in which every element is infinity at the beginning.
Then you read the input and every number you read, you insert it in the first position in S which contains an element greater than it (you can perform this with binary search). If you proceed in this way, S (not including the INFs) keeps the following properties at every step:
- It is an increasing subsequence;
- There exists an increasing subsequence (in the input read so far) with the same lenght of the sequence stored in S, and terminating in the same way of the sequence stored in S.
- Such increasing subsequence is as long as possible.
Note that S is not the LIS itself.
Well, I just solved it using Dijkstra's Algo. Here's the code.
It is somewhere near
N^2
.Simple O(n ^ 2) algorithm is faster than yours.
It was a lack of understanding. Now, when I solved it — I see more ways to do it.
Still, it can't be faster (look at the updated version, where vertices already included in queue are not added). I can't say it certainly, but looks like it's
O(N^2)
Here's mine BIT implementation for the same.