Codeforces Round #806 (Div. 4) F. Yet Another Problem About Pairs Satisfying an Inequality
Call a pair good if it satisfies the condition. Let’s split the inequality into three parts: a i < i a_i < i ai<i, i < a j i<a_j i<aj, a j < j a_j<j aj<j.
Note that if a i ≥ i a_i≥i ai≥i for any i i i, then it can’t be an element of a good pair, because it fails the first and third conditions. So we can throw out all elements of the array satisfying a i ≥ i a_i≥i ai≥i.
For the remaining elements, the first and third inequalities are already satisfied, so we only have to count the number of pairs ( i , j ) (i,j) (i,j) with i < a j i<a_j i<aj. Let’s iterate j j j through the array from the left to the right, and make a list storing all i i i that appear before j j j. Then for each j j j, count the number of i i i less than a j a_j aj by binary searching on the number of elements in the list less than a j a_j aj. Afterwards, add j j j to the end of the list.
Since we iterate from left to right, the list will always remain sorted (we insert the indices of elements, which are increasing from left to right), so the binary search will always work.
The time complexity is O ( n l o g n ) O(nlogn) O(nlogn).
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010;
int tr[N],n;
void add(int x,int y)
{
for(;x<=n;x+=(x&-x))
tr[x]+=y;
}
LL query(int x)
{
LL res=0;
for(;x>0;x-=(x&-x))
res+=tr[x];
return res;
}
int main()
{
int T;cin>>T;
while(T--)
{
memset(tr,0,sizeof tr);
cin>>n;
vector<int> a(n+1);
for(int i=1;i<=n;i++) cin>>a[i];
LL res=0;
for(int i=1;i<=n;i++)
if(a[i]<i)
{
res+=query(a[i]-1);
add(i,1);
}
cout<<res<<endl;
}
return 0;
}