Cod sursa(job #2229952)

Utilizator radustn92Radu Stancu radustn92 Data 8 august 2018 15:59:23
Problema Subsir crescator maximal Scor 100
Compilator java Status done
Runda Arhiva educationala Marime 3.68 kb
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws Exception {
        InputStream inputStream = new FileInputStream("scmax.in");
        OutputStream outputStream = new FileOutputStream("scmax.out");

        try (InputReader inputReader = new InputReader(inputStream);
            PrintWriter printWriter = new PrintWriter(outputStream)) {
            Solver.solve(inputReader, printWriter);
        }
    }

    static class Solver {

        private static final int INF = Integer.MAX_VALUE;

        public static void solve(InputReader inputReader, PrintWriter printWriter) {
            int N = inputReader.nextInt();
            int[] values = new int[N + 1];
            for (int i = 1; i <= N; i++) {
                values[i] = inputReader.nextInt();
            }

            // this array is sorted in increasing order
            ValueEntry[] bestSequence = new ValueEntry[N + 1];
            bestSequence[0] = new ValueEntry(-INF, 0);
            int totalLength = 0;

            int[] previousPos = new int[N + 1];
            Arrays.fill(previousPos, -1);
            for (int i = 1; i <= N; i++) {
                ValueEntry valueToInsert = new ValueEntry(values[i], i);
                int posToInsert;
                if (totalLength == 0 || bestSequence[totalLength].compareTo(valueToInsert) < 0) {
                    posToInsert = ++totalLength;
                } else {
                    posToInsert = Arrays.binarySearch(bestSequence, 0, totalLength + 1, valueToInsert);
                    posToInsert = posToInsert < 0 ? -posToInsert - 1 : posToInsert;
                }

                bestSequence[posToInsert] = valueToInsert;
                previousPos[i] = bestSequence[posToInsert - 1].originalPos;
            }

            printWriter.println(totalLength);
            recons(values, previousPos, bestSequence[totalLength].originalPos, printWriter);

        }

        private static void recons(int[] originalValues, int[] previousElem, int currPos, PrintWriter printWriter) {
            if (currPos <= 0) {
                return;
            }
            recons(originalValues, previousElem, previousElem[currPos], printWriter);

            printWriter.print(originalValues[currPos] + " ");
        }

        private static class ValueEntry implements Comparable<ValueEntry> {
            private int value;

            private int originalPos;

            public ValueEntry(int value, int originalPos) {
                this.value = value;
                this.originalPos = originalPos;
            }

            @Override
            public int compareTo(ValueEntry o) {
                return Integer.compare(value, o.value);
            }
        }
    }

    static class InputReader implements AutoCloseable {

        private BufferedReader bufferedReader;

        private StringTokenizer stringTokenizer;

        public InputReader(InputStream inputStream) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            stringTokenizer = null;
        }

        private String nextToken() {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                try {
                    stringTokenizer = new StringTokenizer(bufferedReader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            return stringTokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        @Override
        public void close() throws Exception {
            bufferedReader.close();
        }
    }
}