#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;   }