Pagini recente » Cod sursa (job #1327164) | Cod sursa (job #191411) | Cod sursa (job #586383) | Cod sursa (job #736777) | Cod sursa (job #2985810)
#include <algorithm>
#include <fstream>
#include <iostream>
#define r inFile
#define w outFile
const int NMAX = 1e5;
int n;
int a[1 + NMAX];
int prev[1 + NMAX];
int dp[1 + NMAX];
// if i remember correctly this should work (famous last words)
int best_val_with_len[1 + NMAX];
void printPath(int i, std::ostream &str) {
if (i == 0) {
return;
}
printPath(prev[i], str);
str << a[i] << ' ';
}
// returns the index not than the value
int binary_search(int start, int end, int value) {
// std::printf("Seeking %d (a = %d)\n", value, a[value]);
int ans = 0;
while (start <= end) {
int midpoint = (start + end) >> 1;
// std::printf("Midpoint = %d (best_val = %d)\n", midpoint,
// best_val_with_len[midpoint]);
if (a[best_val_with_len[midpoint]] < a[value]) {
// std::printf("Value is less than target, saving ans to %d\n", midpoint);
ans = midpoint;
start = midpoint + 1;
} else {
// std::printf("Value is no less than target, not saving shit\n");
end = midpoint - 1;
}
}
return ans;
}
int main() {
std::ifstream inFile("scmax.in");
std::ofstream outFile("scmax.out");
r >> n;
for (int i = 1; i <= n; ++i) {
r >> a[i];
}
// dp[i] - longest str. increasing subarray ending at position i
dp[1] = 1;
prev[1] = 0;
a[0] = -1;
best_val_with_len[0] = 0; // anything can be added after an empty seq
best_val_with_len[1] = 1;
int best_val_length = 1; // actual length of best_val_with_len, so zeros don't
// fuck up my binary search
for (int i = 2; i <= n; ++i) {
// std::printf("Currently at i = %d, array = [ ", i);
// for (int j = 0; j <= best_val_length; ++j) {
// std::printf("%d(%d) ", best_val_with_len[j], a[best_val_with_len[j]]);
// }
// std::printf("]\n");
// find the max length L, so that best_val_with_len[L] < a[i]
// also a[best_val_with_len[]] SHOULD be increasing
int j = binary_search(0, best_val_length, i);
// std::printf("Found j = %d\n", j);
prev[i] = best_val_with_len[j];
dp[i] = dp[best_val_with_len[j]] + 1;
// update the best_val array with the current value
if (a[i] < a[best_val_with_len[dp[i]]]) {
best_val_with_len[dp[i]] = i;
}
// if we found a new max, save it
if (dp[i] > best_val_length) {
best_val_length = dp[i];
best_val_with_len[dp[i]] = i;
}
}
// for (int i = 1; i <= n; ++i) {
// std::printf("%d ", dp[i]);
// }
// std::printf("\n");
int ans = 0;
for (int i = 1; i <= n; ++i) {
if (dp[i] > dp[ans]) {
ans = i;
}
}
w << dp[ans] << '\n';
printPath(ans, w);
return 0;
}