cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2007–2026

274 independently explained problems: 54 Municipal, 54 Regional, 109 National Olympiad and 57 Autumn Tournament tasks. Difficulty labels are learning estimates, not official ratings. Some events share Junior/IATI or Group A/B problem sets. Special formats, scoring limitations and source clarifications are explained on affected tasks. The two previously featured Autumn problems keep their existing permanent URLs.
GROUP B2013 · MediumFenwick tree counting

Count Inversions in a Permutation

Autumn Tournament (2013)

Submission name: invcnt.cpp

Problem summary

Given a permutation of 1…n, count pairs of positions i<j for which a[i]>a[j]. These are inversions: larger values appearing before smaller values.

Input

n, followed by the n permutation values.

Output

The inversion count.

Constraints

2 ≤ n ≤ 1000000; every value 1…n appears exactly once.

Worked example

Original statement sample.

Input

7
4 2 7 1 5 6 3

Output

10

Solution analysis

  1. Process the permutation from left to right. When reading value v at zero-based position i, exactly i earlier values have been seen. If a Fenwick tree counts how many of them are at most v, then i−prefixCount(v) are larger than v and form inversions ending here.
  2. Add that difference to the answer, then insert v into the tree by adding 1 at index v. Query before insertion so the current element is not counted as an earlier one. A Fenwick tree stores partial frequency sums and supports both operations in O(log n).
  3. For the sample, the successive contributions are 0 for 4, 1 for 2, 0 for 7, 3 for 1, 1 for 5, 1 for 6, and 4 for 3. Their sum is 10. A sorted permutation contributes zero everywhere; reverse order contributes n(n−1)/2.
  4. The values are already the index range 1…n, so coordinate compression is unnecessary. Frequencies fit in int, but the total can be 499999500000 for n=1000000, requiring long long.

Why it works

Each inversion has a unique right endpoint. The prefix frequency query counts exactly the earlier values not greater than the current value; subtracting from the number of earlier positions counts exactly its inversion partners. Summing over all right endpoints counts every inversion once.

Complexity: O(n log n) time and O(n) space. Each value makes one Fenwick prefix query and one point update; the input can be processed without storing the permutation.

Watch out. Use a 64-bit answer. Fenwick indices start at 1; index 0 would make the update loop fail to advance. Count earlier larger values, not all larger values in the permutation.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<vector>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    vector<int>tree(n+1,0);
    long long answer=0;
    for(int position=0;position<n;position++){
        int value;
        cin>>value;
        int notGreater=0;
        for(int index=value;index>0;index-=index&-index){
            notGreater+=tree[index];
        }
        // Every earlier greater value forms one inversion ending here.
        answer+=position-notGreater;
        for(int index=value;index<=n;index+=index&-index){
            tree[index]++;
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗