Cod sursa(job #600096)

Utilizator Smaug-Andrei C. Smaug- Data 30 iunie 2011 16:15:43
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cstdio>
#include <algorithm>
using namespace std;

#define MAXN 100005

int T[4*MAXN+10], A[MAXN], P[MAXN], IND[MAXN], B[MAXN], L[MAXN];

int Update(int n, int l, int r, int a, int b, int v){
  if(a<=l && r<=b){
    if(L[T[n]] < L[v])
      T[n]=v;
    return T[n];
  }
  else {
    int mid=((r-l)>>1)+l, x=0, y=0;
    if(a <= mid)
      x=Update(n<<1, l, mid, a, b, v);
    if(b > mid)
      y=Update((n<<1)+1, mid+1, r, a, b, v);
    if(L[x] > L[T[n]])
      T[n]=x;
    if(L[y] > L[T[n]])
      T[n]=y;
    return T[n];
  }
}
  
int Query(int n, int l, int r, int a, int b){
  if(a<=l && r<=b)
    return T[n];
  else {
    int mid=((r-l)>>1)+l, x=0, y=0;
    if(a <= mid)
      x=Query(n<<1, l, mid, a, b);
    if(b > mid)
      y=Query((n<<1)+1, mid+1, r, a, b);
    if(L[x] > L[y])
      return x;
    else
      return y;
  }
}

int main(){

  freopen("scmax.in", "r", stdin);
  freopen("scmax.out", "w", stdout);

  int N, i, cnt, maxp;

  scanf("%d", &N);
  for(i=1; i<=N; i++){
    scanf("%d", A+i);
    IND[i]=A[i];
  }

  sort(IND+1, IND+N+1);

  cnt=1;
  for(i=2; i<=N; i++)
    if(IND[i] != IND[cnt])
      IND[++cnt]=IND[i];

  for(i=1; i<=N; i++)
    B[i]=lower_bound(IND+1, IND+cnt+1, A[i])-IND;

  L[0]=0;
  for(i=1; i<=N; i++){
    P[i]=Query(1, 0, cnt, 0, B[i]-1);
    L[i]=L[P[i]]+1;
    Update(1, 0, cnt, B[i], B[i], i);
  }

  maxp=0;
  for(i=1; i<=N; i++)
    if(L[maxp] < L[i])
      maxp=i;

  printf("%d\n", L[maxp]);
  for(cnt=0, i=maxp; i; i=P[i])
    IND[++cnt]=A[i];

  for(i=cnt; i; i--)
    printf("%d ", IND[i]);
  printf("\n");

  return 0;

}