#include using namespace std; string to_string(string s) { return '"' + s + '"'; } string to_string(bool b) { return b ? "true" : "false"; } template string to_string(bitset bs) { string res; for (size_t i = 0; i < N; ++i) res += '0' + bs[i]; return res; } string to_string(vector v) { string res = "{"; for (bool e : v) res += to_string(e) + ", "; return res += "}"; } template string to_string(pair p); template string to_string(C c) { string res = "{"; for (auto e : c) res += to_string(e) + ", "; return res += "}"; } template string to_string(pair p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } void debug() { cerr << '\n'; } template void debug(Head head, Tail... tail) { cerr << ' ' << to_string(head), debug(tail...); } #ifdef LOCAL #define DEBUG(...) cerr << "[" << #__VA_ARGS__ << "]:", debug(__VA_ARGS__) #else #define DEBUG(...) #endif template struct SegmentTree { const int n; vector t; vector u; SegmentTree(int _n) : n(_n), t(2 * n, E()), u(n, Id()) {} T& operator[](int i) { return t[i + n]; } void build() { for (int i = n - 1; i >= 1; --i) t[i] = Op(t[2 * i], t[2 * i + 1]); } void push() { for (int i = 1; i < n; ++i) push(i); } void apply(int i, U f) { t[i] = Ap(t[i], f); if (i < n) u[i] = Cp(u[i], f); } void push(int i) { if (u[i] == Id()) return; apply(2 * i, u[i]); apply(2 * i + 1, u[i]); u[i] = Id(); } void push(int l, int r) { for (int hl = __lg(l + n), hr = __lg(r - 1 + n); hr > 0; --hl, --hr) { int al = (l + n) >> hl, ar = (r - 1 + n) >> hr; if (al < n) push(al); if (ar != al) push(ar); } } T acc(int l, int r) { push(l, r); T a = E(), b = E(); for (l += n, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) a = Op(a, t[l++]); if (r & 1) b = Op(t[--r], b); } return Op(a, b); } T get(int i) { return acc(i, i + 1); } void act(int l, int r, U f) { push(l, r); for (int i = l + n, j = r + n; i < j; i >>= 1, j >>= 1) { if (i & 1) apply(i++, f); if (j & 1) apply(--j, f); } l = (l + n) >> __builtin_ctz(l + n); while (l >>= 1) t[l] = Op(t[2 * l], t[2 * l + 1]); r = (r + n) >> __builtin_ctz(r + n); while (r >>= 1) t[r] = Op(t[2 * r], t[2 * r + 1]); } void set(int i, T a) { push(i, i + 1); t[i += n] = a; while (i >>= 1) t[i] = Op(t[2 * i], t[2 * i + 1]); } }; struct T { long long v, c; }; T add(T a, T b) { return {a.v + b.v, a.c + b.c}; } T zero() { return {0, 0}; } T add(T a, long long f) { return {a.v + f * a.c, a.c}; } long long add(long long f, long long g) { return f + g; } long long zeroll() { return 0; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int n; cin >> n; vector a(n); for (auto&& e : a) { cin >> e; --e; } vector< vector > idx(1e5); for (int i = 0; i < n; ++i) { idx[a[i]].push_back(i); } SegmentTree st(2 * n + 1); SegmentTree sum(2 * n + 1); for (int i = 0; i <= 2 * n; ++i) { st[i] = {0, i}; sum[i] = {0, 1}; } st.build(); sum.build(); long long res = 0; for (int v = 0; v < 1e5; ++v) { if (idx[v].empty()) { continue; } DEBUG(v, idx[v]); vector b; for (int t = 0; t < (int)idx[v].size(); ++t) { b.push_back(-(idx[v][t] - (t ? idx[v][t - 1] : -1) - 1)); b.push_back(1); } b.push_back(-(n - idx[v].back() - 1)); DEBUG(b); reverse(begin(b), end(b)); int t = n; st.set(t, {t, t}); sum.set(t, {1, 1}); for (int e : b) { if (e == 1) { ++t; res += sum.acc(0, t).v; st.set(t, {st.get(t).v + t, t}); sum.set(t, {sum.get(t).v + 1, 1}); } else { res += sum.acc(0, t + e).v * -e + sum.acc(t + e, t).v * (t - 1) - st.acc(t + e, t).v; st.act(t + e, t, 1); sum.act(t + e, t, 1); t += e; } } t = n; for (int e : b) { if (e == 1) { ++t; st.set(t, {st.get(t).v - t, t}); sum.set(t, {sum.get(t).v - 1, 1}); } else { st.act(t + e, t, -1); sum.act(t + e, t, -1); t += e; } } } cout << res << '\n'; }