#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;
const string nl = "\n";
static struct FastInput {
  static constexpr long long BUF_SIZE = 1 << 20;
  char buf[BUF_SIZE];
  size_t chars_read = 0;
  size_t buf_pos = 0;
  FILE* in = stdin;
  char cur = 0;
  inline char get_char() {
    if (buf_pos >= chars_read) {
      chars_read = fread(buf, 1, BUF_SIZE, in);
      buf_pos = 0;
      buf[0] = (chars_read == 0 ? -1 : buf[0]);
    }
    return cur = buf[buf_pos++];
  }
  inline void tie(long long) {}
  inline explicit operator bool() { return cur != -1; }
  inline static bool is_blank(char c) { return c <= ' '; }
  inline bool skip_blanks() {
    while (is_blank(cur) && cur != -1) {
      get_char();
    }
    return cur != -1;
  }
  inline FastInput& operator>>(char& c) {
    skip_blanks();
    c = cur;
    return *this;
  }
  inline FastInput& operator>>(string& second) {
    if (skip_blanks()) {
      second.clear();
      do {
        second += cur;
      } while (!is_blank(get_char()));
    }
    return *this;
  }
  template <typename T>
  inline FastInput& read_integer(T& n) {
    n = 0;
    if (skip_blanks()) {
      long long sign = +1;
      if (cur == '-') {
        sign = -1;
        get_char();
      }
      do {
        n += n + (n << 3) + cur - '0';
      } while (!is_blank(get_char()));
      n *= sign;
    }
    return *this;
  }
  template <typename T>
  inline typename enable_if<is_integral<T>::value, FastInput&>::type operator>>(
      T& n) {
    return read_integer(n);
  }
  template <typename T>
  inline typename enable_if<is_floating_point<T>::value, FastInput&>::type
  operator>>(T& n) {
    n = 0;
    if (skip_blanks()) {
      string second;
      (*this) >> second;
      sscanf(second.c_str(), "%lf", &n);
    }
    return *this;
  }
} fast_input;
static struct FastOutput {
  static constexpr long long BUF_SIZE = 1 << 20;
  char buf[BUF_SIZE];
  size_t buf_pos = 0;
  static constexpr long long TMP_SIZE = 1 << 20;
  char tmp[TMP_SIZE];
  FILE* out = stdout;
  inline void put_char(char c) {
    buf[buf_pos++] = c;
    if (buf_pos == BUF_SIZE) {
      fwrite(buf, 1, buf_pos, out);
      buf_pos = 0;
    }
  }
  ~FastOutput() { fwrite(buf, 1, buf_pos, out); }
  inline FastOutput& operator<<(char c) {
    put_char(c);
    return *this;
  }
  inline FastOutput& operator<<(const char* second) {
    while (*second) {
      put_char(*second++);
    }
    return *this;
  }
  inline FastOutput& operator<<(const string& second) {
    for (long long i = 0; i < (long long)second.size(); i++) {
      put_char(second[i]);
    }
    return *this;
  }
  template <typename T>
  inline char* integer_to_string(T n) {
    char* p = tmp + TMP_SIZE - 1;
    if (n == 0) {
      *--p = '0';
    } else {
      bool is_negative = false;
      if (n < 0) {
        is_negative = true;
        n = -n;
      }
      while (n > 0) {
        *--p = (char)('0' + n % 10);
        n /= 10;
      }
      if (is_negative) {
        *--p = '-';
      }
    }
    return p;
  }
  template <typename T>
  inline typename enable_if<is_integral<T>::value, char*>::type stringify(T n) {
    return integer_to_string(n);
  }
  template <typename T>
  inline typename enable_if<is_floating_point<T>::value, char*>::type stringify(
      T n) {
    sprintf(tmp, "%.17f", n);
    return tmp;
  }
  template <typename T>
  inline FastOutput& operator<<(const T& n) {
    auto p = stringify(n);
    for (; *p != 0; p++) {
      put_char(*p);
    }
    return *this;
  }
} fast_output;
template <class T>
struct fenwick {
  long long n;
  vector<T> tree;
  fenwick(const long long _n) {
    n = _n;
    tree.assign(n + 2, 0LL);
  }
  void add(long long pos, T dif) {
    ++pos;
    for (long long i = pos; i <= n; i += (i & -i)) {
      tree[i] += dif;
    }
  }
  void set(long long pos, T val) { add(pos, val - query(pos, pos)); }
  T query(long long l) {
    ++l;
    T sum = 0;
    for (long long i = l; i > 0; i -= (i & -i)) {
      sum += tree[i];
    }
    return sum;
  }
  T query(long long l, long long r) { return query(r) - query(l - 1); }
};
int32_t main() {
  ios::sync_with_stdio(0);
  fast_input.tie(0);
  long long n;
  fast_input >> n;
  vector<long long> a(n);
  for (auto& i : a) {
    fast_input >> i;
  }
  vector<long long> b = a;
  sort(b.begin(), b.end());
  b.resize(unique(b.begin(), b.end()) - b.begin());
  for (long long i = 0; i < n; ++i) {
    a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin();
  }
  vector<long long> cnt((long long)1e6 + 100);
  vector<long long> hld, hld1;
  for (long long i = 0; i < n; ++i) {
    hld.push_back(++cnt[a[i]]);
  }
  reverse(a.begin(), a.end());
  fill(cnt.begin(), cnt.end(), 0LL);
  for (long long i = 0; i < n; ++i) {
    hld1.push_back(++cnt[a[i]]);
  }
  reverse(a.begin(), a.end());
  fenwick<long long> ft((long long)1e6 + 100);
  long long ans = 0;
  for (long long i = n - 2; i >= 0; --i) {
    ft.add(hld1[n - i - 2], 1);
    ans += ft.query(hld[i] - 1);
  }
  fast_output << ans << nl;
}
