Cod sursa(job #3222641)

Utilizator Alex_DumitrascuAlex Dumitrascu Alex_Dumitrascu Data 11 aprilie 2024 10:32:06
Problema Subsir crescator maximal Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <bits/stdc++.h>
#define pas (i&(-i))
//https://www.geeksforgeeks.org/longest-increasing-subsequence-using-bit/
using namespace std;
int v [100005];
int vbak[100005];
int aib[100005];
int dp[100005];
set <pair<int, int>> s;
map <int, int> mp;
int n;
void compress()
{
    for (int i=1; i<=n; i++) {
        s.insert({v[i], i});
    }
    int i=1, prev=-1;
    for (auto it=s.begin(); it!=s.end(); it++) {
        pair <int, int> p=*it;
        if (p.first==prev) {
            v[p.second]=i-1;
            mp[i-1]=p.first;
        }
        else {
           v[p.second]=i;
           mp[i]=p.first;
           i++;
        }
        prev=p.first;
    }
    s.clear();
}
int query (int poz)
{
    int maxi=0;
    for (int i=poz; i>0; i-=pas) {
        if (dp[aib[i]]>dp[maxi]) {
            maxi=aib[i];
        }
    }
    return maxi;
}
void update (int poz, int ind)
{
    for (int i=poz; i<=n; i+=pas) {
        if (dp[ind]>dp[aib[i]]) {
            aib[i]=ind;
        }
    }
}
void debug (int arr[])
{
    for (int i=1; i<=n; i++) {
        cout<<arr[i]<<' ';
    }
    cout<<endl;
}
/*
Subproblema: cel mai lung subsir
crescator maximal care incepe cu pozitia i.
*/
int main()
{
    cin.tie(0); cin.sync_with_stdio(false);
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);
    int elem;
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>v[i];
        vbak[i]=v[i];
    }
    compress();
    //debug(v);
    for (int i=1; i<=n; i++) {
        int pred=query(v[i]-1);
        dp[i]=dp[pred]+1;
        update(v[i], i);
    }
    int bst=0;
    for (int i=1; i<=n; i++) {
        if (dp[bst]<dp[i])
            bst=i;
    }
    //debug(aib);
    //debug(dp);
    cout<<dp[bst];
    /*
    for (int i=n; i>=1; i--) {
        dp[i]=0;
        for (int j=i+1; j<=n; j++) {
            if (v[j]>v[i]&&dp[j]>dp[i]) {
                dp[i]=dp[j];
                succ[i]=j;
            }
        }
        dp[i]++;
    }
    int maxi=-1, poz=0;
    for (int i=1; i<=n; i++) {
        if (dp[i]>maxi) {
            maxi=dp[i];
            poz=i;
        }
    }
    cout<<maxi<<'\n';
    while (succ[poz]!=0) {
        cout<<v[poz]<<' ';
        poz=succ[poz];
    }
    cout<<v[poz]<<' ';
    */
    return 0;
}