E. Tufurama
(主席树)
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
struct node
{
int l , r ;
int sum ;
}tr[N * 40 ] ;
int n , a[N] ;
int idx ,root[N];
long long ans ;
int build(int l , int r )
{
int p = ++idx ;
if(l == r ) return p;
int mid = l + r >> 1 ;
tr[p].l = build(l , mid ) , tr[p].r = build(mid + 1 , r ) ;
return p ;
}
int query(int p , int l , int r , int L , int R)
{
if(L <= l && r <= R ) return tr[p].sum ;
int mid = l +r >> 1 , sum = 0 ;
if(L <= mid ) sum += query(tr[p].l , l , mid , L , R) ;
if(R > mid ) sum += query(tr[p].r , mid + 1 ,r , L,R) ;
return sum;
}
int insert(int p , int l , int r , int k )
{
int q = ++idx ;
tr[q] = tr[p] ;
if(l == r )
{
tr[q].sum ++ ;
return q ;
}
int mid = l + r >> 1 ;
if(k <= mid ) tr[q].l = insert(tr[q].l , l , mid , k ) ;
else tr[q].r = insert(tr[q].r, mid + 1 , r , k ) ;
tr[q].sum = tr[tr[q].l].sum + tr[tr[q].r ].sum ;
return q ;
}
int main()
{
int n ;
cin>>n;
root[0] = build(1 , n ) ;
for(int i = 1 ; i <= n ; i ++ )
{
cin>>a[i] ;
a[i] = min(a[i] , n ) ;
ans += (long long)query(root[min(i - 1 , a[i])] , 1 , n , i , n ) ;
root[i] = insert(root[i - 1 ] , 1 , n , a[i ]) ;
}
cout<<ans ;
return 0 ;
}