Pagini recente » Cod sursa (job #1142433) | Cod sursa (job #937090) | Monitorul de evaluare | Cod sursa (job #1643478) | Cod sursa (job #2240497)
#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;
vector<int> ans;
};
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;
nodes[node].ans.clear();
if (st < dr) {
int mij = (st + dr) / 2;
initSegmentTree(node * 2, st, mij);
initSegmentTree(node * 2 + 1, mij + 1, dr);
}
}
void updateSegmetTree(int node, int pos, vector<int> &val) {
if (nodes[node].st == nodes[node].dr) {
nodes[node].ans = val;
return;
}
int mij = (nodes[node].st + nodes[node].dr) / 2;
if (pos <= mij) {
updateSegmetTree(node * 2, pos, val);
} else {
updateSegmetTree(node * 2 + 1, pos, val);
}
int sizeSubarbSt = nodes[node * 2].ans.size(), sizeSubarbDr = nodes[node * 2 + 1].ans.size();
if (sizeSubarbSt == sizeSubarbDr) {
if (nodes[node * 2].ans[sizeSubarbSt - 1] > nodes[node * 2 + 1].ans[sizeSubarbDr - 1]) {
nodes[node].ans = nodes[node * 2 + 1].ans;
} else {
nodes[node].ans = nodes[node * 2].ans;
}
} else if (sizeSubarbSt > sizeSubarbDr) {
nodes[node].ans = nodes[node * 2].ans;
} else {
nodes[node].ans = nodes[node * 2 + 1].ans;
}
}
vector<int> querySegmentTree(int node, int st, int dr) {
if (dr == 0) {
vector<int> emptyVec;
return emptyVec;
}
if (nodes[node].st >= st && nodes[node].dr <= dr) {
return nodes[node].ans;
}
int mij = (nodes[node].st + nodes[node].dr) / 2;
vector<int> subarbStVec, subarbDrVec;
if (st <= mij) {
subarbStVec = querySegmentTree(node * 2, st, dr);
}
if (dr > mij) {
subarbDrVec = querySegmentTree(node * 2 + 1, st, dr);
}
int sizeSubarbSt = subarbStVec.size(), sizeSubarbDr = subarbDrVec.size();
if (sizeSubarbSt == sizeSubarbDr) {
if (sizeSubarbSt == 0) {
return subarbStVec;
}
if (subarbStVec[sizeSubarbSt - 1] > subarbDrVec[sizeSubarbDr - 1]) {
return subarbDrVec;
} else {
return subarbStVec;
}
} else if (sizeSubarbSt > sizeSubarbDr) {
return subarbStVec;
} else {
return subarbDrVec;
}
}
int main() {
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);
for (int i = 1; i <= N; ++i) {
vector<int> queryVec = querySegmentTree(1, 1, a[i].second - 1);
queryVec.push_back(a[i].first);
updateSegmetTree(1, a[i].second, queryVec);
}
cout << nodes[1].ans.size() << '\n';
for (int i = 0; i < nodes[1].ans.size(); ++i) {
cout << nodes[1].ans[i] << ' ';
}
return 0;
}