Pagini recente » Profil eudanip | Cod sursa (job #630171) | Cod sursa (job #784423) | Istoria paginii runda/petru_toti | Cod sursa (job #2240621)
#include <fstream>
#include <vector>
#include <algorithm>
#define MAX_N 100005
#define MAX_NODES 265000
using namespace std;
ifstream cin("scmax.in");
ofstream cout("scmax.out");
struct Node {
int st;
int dr;
int lis;
int currentPos;
int prevPos;
int lastVal;
};
struct QueryAnswer {
int prevPos;
int lis;
int lastVal;
int currentPos;
int currentVal;
};
bool mycompare(pair<int, int> &lhs, pair<int, int> &rhs) {
if (lhs.first == rhs.first) {
return lhs.second > rhs.second;
}
return lhs.first < rhs.first;
}
int N;
vector<pair<int, int>> a(MAX_N);
vector<Node> nodes(MAX_NODES);
void initSegmentTree(int node, int st, int dr) {
nodes[node].st = st;
nodes[node].dr = dr;
if (st < dr) {
int mij = (st + dr) / 2;
initSegmentTree(node * 2, st, mij);
initSegmentTree(node * 2 + 1, mij + 1, dr);
nodes[node].currentPos = nodes[node * 2].currentPos;
}
else {
nodes[node].currentPos = st;
}
}
void updateSegmetTree(int node, int pos, QueryAnswer &queryAns) {
if (nodes[node].st == nodes[node].dr) {
nodes[node].lastVal = queryAns.currentVal;
nodes[node].lis = queryAns.lis + 1;
nodes[node].prevPos = queryAns.currentPos;
return;
}
int mij = (nodes[node].st + nodes[node].dr) / 2;
if (pos <= mij) {
updateSegmetTree(node * 2, pos, queryAns);
}
else {
updateSegmetTree(node * 2 + 1, pos, queryAns);
}
Node leftNode = nodes[node * 2], rightNode = nodes[node * 2 + 1];
if (leftNode.lis == rightNode.lis) {
if (leftNode.lastVal > rightNode.lastVal) {
nodes[node].currentPos = rightNode.currentPos;
nodes[node].lastVal = rightNode.lastVal;
nodes[node].lis = rightNode.lis;
nodes[node].prevPos = rightNode.prevPos;
}
else {
nodes[node].currentPos = leftNode.currentPos;
nodes[node].lastVal = leftNode.lastVal;
nodes[node].lis = leftNode.lis;
nodes[node].prevPos = leftNode.prevPos;
}
} else if (leftNode.lis > rightNode.lis) {
nodes[node].currentPos = leftNode.currentPos;
nodes[node].lastVal = leftNode.lastVal;
nodes[node].lis = leftNode.lis;
nodes[node].prevPos = leftNode.prevPos;
} else {
nodes[node].currentPos = rightNode.currentPos;
nodes[node].lastVal = rightNode.lastVal;
nodes[node].lis = rightNode.lis;
nodes[node].prevPos = rightNode.prevPos;
}
}
QueryAnswer querySegmentTree(int node, int st, int dr) {
QueryAnswer queryAnswer;
if (dr == 0) {
queryAnswer.prevPos = 0;
queryAnswer.lis = 0;
queryAnswer.lastVal = 0;
queryAnswer.currentPos = 0;
return queryAnswer;
}
if (nodes[node].st >= st && nodes[node].dr <= dr) {
queryAnswer.prevPos = nodes[node].prevPos;
queryAnswer.lis = nodes[node].lis;
queryAnswer.lastVal = nodes[node].lastVal;
queryAnswer.currentPos = nodes[node].currentPos;
return queryAnswer;
}
int mij = (nodes[node].st + nodes[node].dr) / 2;
QueryAnswer leftSubarbQueryAnswer, rightSubarbQueryAnswer;
leftSubarbQueryAnswer.prevPos = 0;
leftSubarbQueryAnswer.lis = 0;
leftSubarbQueryAnswer.lastVal = 0;
leftSubarbQueryAnswer.currentPos = 0;
rightSubarbQueryAnswer.prevPos = 0;
rightSubarbQueryAnswer.lis = 0;
rightSubarbQueryAnswer.lastVal = 0;
rightSubarbQueryAnswer.currentPos = 0;
if (st <= mij) {
leftSubarbQueryAnswer = querySegmentTree(node * 2, st, dr);
}
if (dr > mij) {
rightSubarbQueryAnswer = querySegmentTree(node * 2 + 1, st, dr);
}
if (leftSubarbQueryAnswer.lis == rightSubarbQueryAnswer.lis) {
if (leftSubarbQueryAnswer.lastVal > rightSubarbQueryAnswer.lastVal) {
return rightSubarbQueryAnswer;
} else {
return leftSubarbQueryAnswer;
}
} else if (leftSubarbQueryAnswer.lis > rightSubarbQueryAnswer.lis) {
return leftSubarbQueryAnswer;
} else {
return rightSubarbQueryAnswer;
}
}
int main() {
cin.sync_with_stdio(false);
cout.sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= N; ++i) {
cin >> a[i].first;
a[i].second = i;
}
sort(a.begin() + 1, a.begin() + 1 + N, mycompare);
initSegmentTree(1, 1, N);
QueryAnswer queryAnswer;
for (int i = 1; i <= N; ++i) {
queryAnswer = querySegmentTree(1, 1, a[i].second - 1);
queryAnswer.currentVal = a[i].first;
updateSegmetTree(1, a[i].second, queryAnswer);
}
int currentInterval = nodes[1].currentPos;
vector<int> sol;
do {
queryAnswer = querySegmentTree(1, currentInterval, currentInterval);
sol.push_back(queryAnswer.lastVal);
currentInterval = queryAnswer.prevPos;
} while (queryAnswer.lis > 1);
cout << sol.size() << '\n';
for (int i = sol.size() - 1; i >= 0; --i) {
cout << sol[i] << ' ';
}
return 0;
}