#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
#pragma GCC optimize("O2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
const double pi =
    3.141592653589793238462643383279502884197169399375105820974944;
const double e = 2.71828182845904523536028747135266249775724709369995;
const long long mod = 1e9 + 7;
const long long inf = 2e18;
const long long ninf = -2e18;
const long long nax = 1e6;
long long power(long long x, long long y, long long mod) {
  long long ans = 1;
  x %= mod;
  while (y) {
    if (y & 1) ans = (x * ans) % mod;
    x = (x * x) % mod;
    y >>= 1;
  }
  return ans;
}
template <class T>
struct search_buckets {
  int N, BUCKET_SIZE;
  vector<T> arr, buckets;
  search_buckets(const vector<T>& initial = {}) {
    arr = buckets = initial;
    N = arr.size();
    BUCKET_SIZE = 3 * sqrtl(N * log(N + 1)) + 1;
    cerr << "Bucket size: " << BUCKET_SIZE << "\n";
    for (int start = 0; start < N; start += BUCKET_SIZE) {
      sort(buckets.begin() + start, buckets.begin() + get_bucket_end(start));
    }
  }
  int get_bucket_end(int bucket_start) const {
    return min(bucket_start + BUCKET_SIZE, N);
  }
  int bucket_less_than(int bucket_start, T value) const {
    auto begin = buckets.begin() + bucket_start;
    auto end = buckets.begin() + get_bucket_end(bucket_start);
    return lower_bound(begin, end, value) - begin;
  }
  int less_than(int start, int end, T value) const {
    int count = 0;
    int bucket_start = start - start % BUCKET_SIZE;
    int bucket_end = min(get_bucket_end(bucket_start), end);
    if (start - bucket_start < bucket_end - start) {
      while (start > bucket_start) {
        count -= arr[--start] < value;
      }
    } else {
      while (start < bucket_end) {
        count += arr[start++] < value;
      }
    }
    if (start == end) return count;
    bucket_start = end - end % BUCKET_SIZE;
    bucket_end = get_bucket_end(bucket_start);
    if (end - bucket_start < bucket_end - end) {
      while (end > bucket_start) {
        count += arr[--end] < value;
      }
    } else {
      while (end < bucket_end) {
        count -= arr[end++] < value;
      }
    }
    while (start < end && get_bucket_end(start) <= end) {
      count += bucket_less_than(start, value);
      start = get_bucket_end(start);
    }
    assert(start == end);
    return count;
  }
  int prefix_less_than(int n, T value) const { return less_than(0, n, value); }
  void modify(int index, T value) {
    int bucket_start = index - index % BUCKET_SIZE;
    int old_pos = bucket_start + bucket_less_than(bucket_start, arr[index]);
    int new_pos = bucket_start + bucket_less_than(bucket_start, value);
    if (old_pos < new_pos) {
      copy(buckets.begin() + old_pos + 1, buckets.begin() + new_pos,
           buckets.begin() + old_pos);
      new_pos--;
    } else {
      copy_backward(buckets.begin() + new_pos, buckets.begin() + old_pos,
                    buckets.begin() + old_pos + 1);
    }
    buckets[new_pos] = value;
    arr[index] = value;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  time_t t1, t2;
  t1 = clock();
  int n;
  cin >> n;
  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    a[i] = min(a[i], n);
  }
  search_buckets<int> st(a);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    int lol = a[i] - st.less_than(1, a[i] + 1, i) - (a[i] >= i);
    ;
    ans += lol;
  }
  cout << ans / 2;
  t2 = clock();
  cerr << "\n"
       << "time taken: " << t2 - t1 << "\n";
  return 0;
}
