Cod sursa(job #347117)

Utilizator marcelcodreaCodrea Marcel marcelcodrea Data 11 septembrie 2009 02:03:47
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
/* L.I.S. cu Arbori indexati binari + Implementez parsare sa vad cat castig la timp
   O(N * log N)
   Intra fara parsare, spre deosebire de situatia cand folosesc Arbori de intervale

*/
#include<stdio.h>
#include<algorithm>
#include<string.h>

using namespace std;

int sir[100010];
int S[100010];
int BIT[100010];
int pozF;
int contor;
char charsir[11000009];
int SandD[100010];
int n;
int bst[100010];
int i;
int maxG;
int CautBin(int val)
{
    int st = 1;
    int dr = n;
    while (st <= dr)
     {
         if (SandD[(st + dr) / 2] > val) dr = (st + dr) / 2 - 1;
          else
         if (SandD[(st + dr) / 2] < val) st = (st + dr) / 2 + 1;
          else
           return (st + dr) / 2;
     }
     return 0;
}
int Query(int p)
{
    int max = 0;
    while (p > 0)
      {
          if (max < BIT[p]) max = BIT[p];
          p -= (p & -p);
      }
     return max;
}
void Update(int p, int maxL)
{
    while (p <= n)
     {
         if (maxL > BIT[p]) BIT[p] = maxL;
         p += (p & -p);
     }
}
void PrintSol(int now, int val)
{
    if (bst[now] > 1)
     {
         for(i = now; bst[i] != val; i--);
         PrintSol(i, val - 1);
     }
    printf("%d ",SandD[sir[now]]);



}
void Parse()
{
    fgets(charsir, n * 11, stdin);
    int i = 0;
    int nr = 0;
    while (charsir[i] != '\n')
     {
         if (charsir[i] != ' ') nr = nr * 10 + charsir[i] - '0';
                        else
                         {
                             sir[++contor] = nr;
                             S[contor] = nr;
                             nr = 0;
                         }
         i++;
     }
     sir[++contor] = nr;
     S[contor] = nr;
     nr = 0;

}
int main()
{
        freopen("scmax.in","r",stdin);
        freopen("scmax.out","w",stdout);

        scanf("%d\n",&n);

       /* for(int i = 1; i <= n ; i++)
        {
         scanf("%d",&sir[i]);
         S[i] = sir[i];
        }*/
        Parse();
        sir[0] = n;
        sort(S + 1, S + n + 1);
        for(int i = 1; i <= n ; i++)
         {
             if (S[i] != S[i-1]) SandD[++SandD[0]] = S[i];
         }
        n = SandD[0];
        for(int i = 1; i <= sir[0]; i++)
        {
         sir[i] = CautBin(sir[i]);
        }


        for(int i = 1; i <= sir[0]; i++)
         {
             int best = 0;
             if (sir[i] > 1)
             best = Query(sir[i] - 1);
             bst[i] = best + 1;
             Update(sir[i],best + 1);
         }
         for(int i = 1; i <= sir[0]; i++)
          {
              if (maxG < bst[i])
               {
                   maxG = bst[i];
                   pozF = i;
               }
          }
         printf("%d\n", maxG);
         PrintSol(pozF, maxG - 1);


}