Cod sursa(job #2027179)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 25 septembrie 2017 18:46:15
Problema Subsir 2 Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include<bits/stdc++.h>
#define maxN 5005
#define lsb(i) (i&(-i))
using namespace std;
pair<int,int> p[maxN];
vector<int> L[maxN];
int AIB[maxN],best[maxN],pre[maxN],maxim,v[maxN],n,dp[maxN],cnt;
bool seen[maxN];
int bestind;
inline void Update(int pos,int val,int ind)
{
    for(int i=pos;i<=cnt;i+=lsb(i))
    {
        if(val>AIB[i] || (val==AIB[i] && v[ind]<v[best[i]]))
        {
            AIB[i]=val;
            best[i]=ind;
        }
    }
}
int ans[maxN];
inline pair<int,int> Query(int pos)
{
    int q=0,bst=0;
    for(int i=pos;i>=1;i-=lsb(i))
    {
        if(AIB[i]>q || (q==AIB[i] && v[best[i]]<v[bst]))
        {
            q=AIB[i];
            bst=best[i];
        }
    }
    return make_pair(q,bst);
}
deque<int> q;
inline void dfs(int nod)
{
    ans[nod]=dp[nod];
    seen[nod]=1;
    for(vector<int>::iterator it=L[nod].begin();it!=L[nod].end();it++)
    {
        if(!seen[*it])
        {
            dfs(*it);
            ans[nod]=max(ans[nod],ans[*it]);
        }
    }
}
bool cmp(int x,int y)
{
    return v[x]<v[y];
}
inline void Reconst(int nod)
{
    q.push_back(nod);
    seen[nod]=1;
 //   ans[nod]=dp[nod];
    sort(L[nod].begin(),L[nod].end(),cmp);
    for(vector<int>::iterator it=L[nod].begin();it!=L[nod].end();it++)
    {
        if(!seen[*it])
        {
            if(ans[*it]==ans[nod])
            {
                Reconst(*it);
                break;
            }
        }
    }
}
int ind[maxN];
int main()
{
    freopen("subsir2.in","r",stdin);
    freopen("subsir2.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&v[i]);
        p[i]={v[i],i};
    }
    sort(p+1,p+n+1);
    cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(i>1 && p[i].first>p[i-1].first) cnt++;
        v[p[i].second]=cnt;
    }
    for(int i=1;i<=n;i++)
    {
        dp[i]=1;
        pair<int,int> q=Query(v[i]);
        pre[i]=0;
        if(q.first)
        {
            dp[i]=q.first+1;
            pre[i]=q.second;
            seen[pre[i]]=1;
            L[pre[i]].push_back(i);
            L[i].push_back(pre[i]);
        }
        Update(v[i],dp[i],i);
    }
    for(int i=1;i<=n;i++)
    {
        if(!seen[i]) //nu mai extinde
        {
            if(dp[i]>maxim)
            {
                maxim=dp[i];
                bestind=i;
            }
        }
    }
    printf("%d\n",maxim);
    memset(seen,0,sizeof(seen));
    int di=0;
    for(int i=1;i<=n;i++)
    {
        if(dp[i]==1)
        {
        memset(ans,0,sizeof(ans));
        dfs(i);
        if(ans[i]==maxim) ind[++di]=i;
        }
    }
    sort(ind+1,ind+di+1,cmp);
    memset(seen,0,sizeof(seen));
 //   memset(ans,0,sizeof(ans));
    Reconst(ind[1]);

    while(!q.empty())
    {
        printf("%d ",q.front());
        q.pop_front();
    }
    return 0;
}