HackerRank

Good one to learn Binary Indexed Tree (Fenwick Tree). Simply grabbed the editorial's code but with comments.

#include <cmath>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
using namespace std;

#define MAX_NUM 100001

/////////////////////////
class FenwickTree
{
    long long tree[MAX_NUM];
public:
    //    Utility methods: in terms of the original array BIT operates on
    //
    FenwickTree()
    {
        for(int i = 0; i < MAX_NUM; i ++)
            tree[i] = 0;
    }
    long long get(int inx)
    {
        return query(inx) - query(inx - 1);
    }
    void set(int inx, long long val)
    {
        long long curr = get(inx);
        update(inx, val - curr);
    }
    //    BIT core methods
    //
    void update(int inx, long long val)
    {
        //    BIT: from child going up to tree root
        //         so ?????????? last valid bit in each iteration
        //         
        while(inx <= MAX_NUM)
        {
            tree[inx] += val;
            inx += (inx & -inx);    // backwards as query
        }
    }
    long long query(int inx)
    {
        long long sum = 0;
        //    BIT: from parent going down to children
        //         so eliminating last valid bit in each iteration
        //         like addition in binary representation
        while(inx > 0)    // lower valid bits to higher valid ones. cannot be zero
        {
            sum += tree[inx];
            inx -= (inx & -inx);
        }
        return sum;
    }
};

FenwickTree t1, t2, t3;

/////////////////////////

int main() 
{    
    set<int> s;
    map<int, int> m;

    //    Get input
    int n; cin >> n;
    vector<int> in(n);
    for(int i = 0; i < n; i ++)
    {
        cin >> in[i];
        s.insert(in[i]);
    }
    
    //        
    int cnt = 1;
    for (auto &v : s)    // sorted
        m[v] = cnt ++;

    for(auto &v : in)
    {
        int i = m[v];
        t1.set(i, 1);    // Existence: there's one number at i-th position in a sorted sequence
                        //              and then t1 updates all accumulated records (+1 all the way up)
        t2.set(i, t1.query(i - 1)); // set number of sum(existed smaller numbers): no. of tuples
        t3.set(i, t2.query(i - 1)); // similar as above
    }
    cout << t3.query(MAX_NUM) << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/tonix/p/4518738.html