#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#define ENVIRONMENT_LINKED_ACL #ifdef ENVIRONMENT_LINKED_ACL #include #endif //#define ENVIRONMENT_LINKED_BOOST #ifdef ENVIRONMENT_LINKED_BOOST #include #include #endif using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using lpair = std::pair; #define REP(i, a, b) for (ll i = a; i < b; ++i) #define REPREV(i, a, b) for (ll i = a; i > b; --i) const int _ = []() { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(10); return 0; }(); template void resize(value_t& v, const value_t& val) { v = val; } template void resize(std::vector& v, const value_t& val, int size, arg_t... arg) { v.resize(size); for (auto& c : v) resize(c, val, arg...); } template void chmin(A& a, const B& b) { a = min(a, static_cast(b)); }; template void chmax(A& a, const B& b) { a = max(a, static_cast(b)); }; //applyは左にかける template struct lazy_segtree { private: std::function composition; std::function mapping; std::function op; std::function id; std::function e; std::vector lazy; std::vector dat; long long size; long long log; void update(int ind) { dat[ind] = op(dat[ind << 1 | 0], dat[ind << 1 | 1]); } void node_apply(int ind, const M& m) { dat[ind] = mapping(m, dat[ind]); if (ind < size) lazy[ind] = composition(m, lazy[ind]); } void prop(int ind) { node_apply(ind << 1 | 0, lazy[ind]); node_apply(ind << 1 | 1, lazy[ind]); lazy[ind] = id(); } public: lazy_segtree() : size{0}, log{0} {} lazy_segtree(long long _n, // std::function _op, // std::function _e, // std::function _mapping, // std::function _composition, // std::function _id) // : op{_op}, // e{_e}, // mapping{_mapping}, // composition{_composition}, // id{_id} // { size = 1, log = 0; while (size < _n) size <<= 1, ++log; dat.resize(2 * size, e()); lazy.resize(2 * size, id()); } lazy_segtree(const std::vector& _src, // std::function _op, // std::function _e, // std::function _mapping, // std::function _composition, // std::function _id) // : op{_op}, // e{_e}, // mapping{_mapping}, // composition{_composition}, // id{_id} // { size = 1, log = 0; while (size < _src.size()) size <<= 1, ++log; dat.resize(2 * size); lazy.resize(2 * size, id()); for (int i = 0; i < _src.size(); ++i) dat[i + size] = _src[i]; } //[l,r) mは左にかける void apply(long long l, long long r, const M& m) { assert(0 <= l && l <= r && r <= size); if (l == r) return; l += size; r += size; for (int i = log; i >= 1; --i) { if ((l >> i) << i != l) prop(l >> i); if ((r >> i) << i != r) prop((r - 1) >> i); } long long a = l, b = r; while (a < b) { if (a & 1) node_apply(a++, m); if (b & 1) node_apply(--b, m); a >>= 1, b >>= 1; } for (int i = 1; i <= log; ++i) { if ((l >> i) << i != l) update(l >> i); if ((r >> i) << i != r) update((r - 1) >> i); } } //O(1) T all_prod() { return dat[1]; } //[l,r) T query(long long l, long long r) { assert(0 <= l && l <= r && r <= size); l += size, r += size; for (int i = log; i >= 1; --i) { if ((l >> i) << i != l) prop(l >> i); if ((r >> i) << i != r) prop((r - 1) >> i); } T tmp_l = e(); T tmp_r = e(); while (l < r) { if (l & 1) tmp_l = op(tmp_l, dat[l++]); if (r & 1) tmp_r = op(dat[--r], tmp_r); l >>= 1, r >>= 1; } return op(tmp_l, tmp_r); } T elem(long long i) { assert(0 <= i && i < size); i += size; for (int j = log; j >= 1; --j) prop(i >> j); return dat[i]; } void set(long long i, const T& value) { assert(0 <= i && i < size); i += size; for (int j = log; j >= 1; --j) prop(i >> j); dat[i] = value; for (int j = 1; j <= log; ++j) update(i >> j); } //x <= rで、cond[x-1, r) = falseとなる最大のx 存在しなければ0 int search_left(long long r, std::function cond) { assert(0 <= r && r <= size); assert(cond(e())); if (r == 0) return 0; r += size; for (int j = log; j >= 1; --j) prop((r - 1) >> j); T tmp = e(); do { --r; while (r % 2 && r > 1) r >>= 1; T next = op(dat[r], tmp); if (cond(next)) { tmp = next; continue; } while (r < size) { prop(r); r <<= 1; next = op(dat[++r], tmp); if (cond(next)) { --r; tmp = next; } } return r - size + 1; } while ((r & -r) != r); return 0; } //l <= x で、cond(op[l,x+1))=falseとなる最小のx 存在しなければsize int search_right(long long l, std::function cond) { assert(0 <= l && l <= size); assert(cond(e())); if (l == size) return size; l += size; T tmp = e(); do { while (l % 2 == 0) l >>= 1; T next = op(tmp, dat[l]); if (cond(next)) { ++l; tmp = next; continue; } while (l < size) { prop(l); l <<= 1; next = op(tmp, dat[l]); if (cond(next)) { ++l; tmp = next; } } return l - size; } while ((l & -l) != l); return size; } }; int main() { ll n; cin >> n; vector A(n); map M; REP(i, 0, n) { cin >> A[i]; if (M.count(A[i]) == 0) M[A[i]] = {i, i}; chmax(M[A[i]].second, i); } lazy_segtree seg{n, [](ll a, ll b) { return a; }, []() { return 0; }, [](ll m, ll a) { return m ? m : a; }, [](ll m1, ll m2) { return m1 ? m1 : m2; }, []() { return 0; }}; for (auto [a, range] : M) { seg.apply(range.first, range.second + 1, a); } REP(i, 0, n) { cout << seg.elem(i); if (i == n - 1) { cout << endl; } else { cout << " "; } } return 0; }