Cod sursa(job #2866977)

Utilizator 100pCiornei Stefan 100p Data 10 martie 2022 09:32:12
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <bits/stdc++.h>
#define pb push_back
#define MAX 100000
#define mp make_pair
#define mod 1000000007
#define ll long long
#define ull unsigned long long
#define fastio ios_base::sync_with_stdio(NULL),cin.tie(NULL),cout.tie(NULL);
#define FILES freopen("scmax.in","r",stdin);\
              freopen("scmax.out","w",stdout);
using namespace std;
int n,a,ans,backk[MAX+5],pos,best,Code[MAX+5],cp[MAX+5];
pair<int,int> pr,tree[MAX*4+5],v[MAX+5];
inline pair<int,int> Max(pair<int,int> a,pair<int,int> b)
{
    return (a.first > b.first ? a : b);
}
void update(int st,int dr,int node,int pz,pair<int,int> val)
{
    if(st == dr)
    {
        tree[node] = Max(tree[node],val);
        return;
    }
    int mid = (st + dr) >> 1;
    if(pz <= mid) update(st,mid,(node<<1)+1,pz,val);
    else update(mid+1,dr,(node<<1)+2,pz,val);
    tree[node] = Max(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void query(int st,int dr,int node,int x,int y)
{
    if(x > y)
        return;
    if(st >= x && y >= dr)
    {
        pr = Max(pr,tree[node]);
        return;
    }
    int mid = (st + dr) >> 1;
    if(x <= mid) query(st,mid,(node<<1)+1,x,y);
    if(mid < y) query(mid+1,dr,(node<<1)+2,x,y);
}
int main()
{
    fastio
    FILES
    cin >> n;
    for(int i = 1;i <= n; ++i)
        cin >> a,v[i].first = cp[i] = a,v[i].second = i;
    int code = 1;
    sort(v+1,v+1+n);
    for(int i = 1;i <= n; ++i)
    {
        int x = v[i].first;
        while(i <= n && x == v[i].first)
            Code[v[i].second] = code,i++;
        i--;
        code++;
    }
    code--;
    for(int i = 1;i <= n; ++i)
    {
        pr = {0,0};
        query(1,code,0,1,Code[i]-1);
        backk[i] = pr.second;
        update(1,code,0,Code[i],{pr.first+1,i});
        if(pr.first + 1 > best) best = pr.first + 1,pos = i;
    }
    vector<int> ans;
    while(backk[pos])
    {
        ans.pb(cp[pos]);
        pos = backk[pos];
    }
    cout << best << '\n';
    ans.pb(cp[pos]);
    for(int i = ans.size() - 1;i >= 0; --i)
        cout << ans[i] << ' ';
}