Pagini recente » Cod sursa (job #2325251) | Cod sursa (job #955565) | Cod sursa (job #2971992) | Cod sursa (job #2853688) | Cod sursa (job #3242163)
import java.io.*;
import java.util.*;
public class Main {
static final String INPUT_FILE = "scmax.in";
static final String OUTPUT_FILE = "scmax.out";
public static class TokenizedReader {
private final BufferedReader reader;
private StringTokenizer tokenizer;
TokenizedReader(String filePath) throws FileNotFoundException {
reader = new BufferedReader(new FileReader(filePath));
}
private String nextToken() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
private int nextInt() {
return Integer.parseInt(nextToken());
}
public void close() throws IOException {
reader.close();
}
}
public static void main(String[] args) throws IOException {
TokenizedReader reader = new TokenizedReader(INPUT_FILE);
PrintWriter writer = new PrintWriter(OUTPUT_FILE);
solve(reader, writer);
reader.close();
writer.flush();
writer.close();
}
static class FenwickTreeMax {
private final int[] value;
private final int[] maxIndex;
private final int n;
public FenwickTreeMax(int n) {
this.n = n;
this.maxIndex = new int[n + 1];
this.value = new int[n + 1];
Arrays.fill(this.maxIndex, 0);
Arrays.fill(this.value, 0);
}
public int queryMaxIdx(int index) {
int currMaxIdx = 0;
while (index > 0) {
if (value[maxIndex[index]] > value[currMaxIdx]) {
currMaxIdx = maxIndex[index];
}
index -= (index & (-index));
}
return currMaxIdx;
}
public void update(int index, int posIdx) {
int newValue = value[posIdx];
while (index <= n) {
if (newValue > value[maxIndex[index]]) {
maxIndex[index] = posIdx;
}
index += (index & (-index));
}
}
}
public static void solve(TokenizedReader reader,
PrintWriter writer) {
int n = reader.nextInt();
// for storing the original array
int[] original = new int[n + 1];
// for storing the rank of the original element
int[] rank = new int[n + 1];
// for storing the sorted elements
int[] uniqueSorted = new int[n + 1];
for (int i = 1; i <= n; ++i) {
original[i] = rank[i] = uniqueSorted[i] = reader.nextInt();
}
Arrays.sort(uniqueSorted);
// compress rank array removing duplicates
int uniqueCount = 1;
for (int i = 2; i <= n; ++i) {
if (uniqueSorted[i] != uniqueSorted[uniqueCount]) {
uniqueSorted[++uniqueCount] = uniqueSorted[i];
}
}
// build rank array
for (int i = 1; i <= n; ++i) {
rank[i] = Arrays.binarySearch(uniqueSorted, 1, uniqueCount + 1, rank[i]);
}
int[] prev = new int[n + 1];
// build a fenwick tree for storing the "index" of the element with the maximum partial best in the interval [1, i]
FenwickTreeMax fenwickTree = new FenwickTreeMax(n);
for (int i = 1; i <= n; ++i) {
// check the maximum partial best in the interval [1, i - 1] and set as prev[i]
prev[i] = fenwickTree.queryMaxIdx(rank[i] - 1);
// update current best
fenwickTree.value[i] = 1 + fenwickTree.value[prev[i]];
fenwickTree.update(rank[i], i);
}
int maxIdx = fenwickTree.queryMaxIdx(n);
int best = fenwickTree.value[maxIdx];
writer.println(best);
// build the solution
int[] result = new int[best + 1];
result[0] = 0;
for (int i = maxIdx; i > 0; i = prev[i]) {
result[++result[0]] = original[i];
}
for (int i = result[0]; i > 0; --i) {
writer.write(result[i] + " ");
}
}
}