View difference between Paste ID: 6zaKbKRS and ytYDayy0
SHOW: | | - or go back to the newest paste.
1
/*
2
Longest Non-Decreasing Subsequence
3
Vremenska slozenost: O(N*logN)
4
Memorija: O(N)
5
*/
6
7
#include <bits/stdc++.h>
8
using namespace std;
9
10
const int N=1e5+10;
11
12
struct Node
13
{
14
    int parent;
15
    Node()
16
    {
17
        parent=-1;
18
    }
19
} g[N]; //graf (stablo) koji sluzi za rekonstrukciju LISa
20
21
int n, a[N], dp[N], lis; // dp[i] <==> idx najmanjeg broja kom je LIS duzine i
22
vector<int> sol; //rekonstruisan LIS
23
24
int bs (int x, int bound) //hocu broj X da stavim na postojeci LIS duzine RET
25
{
26-
    int l=0, r=bound, mid, ret=0;
26+
    int l=1, r=bound, mid, ret=0;
27
    while (l<=r)
28
    {
29
        mid=l+(r-l)/2;
30
        if (dp[mid]==-1 || a[dp[mid]]>x) r=mid-1;
31
        else
32
        {
33
            ret=mid;
34
            l=mid+1;
35
        }
36
    }
37
    return ret+1; //novi LIS ce biti duzine RET+1
38
}
39
40
void dfs (int v)
41
{
42
    sol.push_back(v);
43
    if (g[v].parent==-1) return;
44
    dfs (g[v].parent);
45
}
46
47
void reconstruct ()
48
{
49
    dfs (dp[lis]);
50
    reverse (sol.begin(), sol.end()); //tehnicki suvisno
51
}
52
53
int main()
54
{
55
    scanf ("%d", &n);
56
    memset (dp, -1, sizeof dp);
57
58
    for (int i=1;i<=n;i++)
59
    {
60
        scanf ("%d", &a[i]);
61
62
        int idx=bs(a[i], i-1);
63
        lis=max(lis, idx);
64
65
        if (dp[idx]==-1 || a[dp[idx]]>a[i])
66
        {
67
            dp[idx]=i;
68
            if (idx>1) g[i].parent=dp[idx-1]; //koja pozicija je u LISu pre i
69
        }
70
    }
71
72
    reconstruct();
73
74
    printf ("%d\n", lis);
75
    for (int i=0;i<lis;i++) printf ("%d ", a[sol[i]]);
76
77
    return 0;
78
}