coding-16

published at Jan 12, 2025

#daily-coding

Kattis – gcpc

Completed today’s daily coding a bit later than the others, which can all be attributed to waking up late (right now is 9:11pm). This problem is really interesting because I got to used a cool trick from halim. That is policy-based data structures.

Essentially, this gives me an STL-like tree that also implements fast select and rank operations, called an “ordered statistics tree” by Halim.

An example (from Halim’s book):

#include <bits/stdc++.h> 
using namespace std; 
#include <bits/extc++.h> // pbds 

using namespace __gnu_pbds; 

typedef tree<int, null_type, less<int>,
			rb_tree_tag, tree_order_statistics_node_update> ost; 

int main() { 
	int n = 9; 
	int A[] = { 2, 4, 7,10,15,23,50,65,71}; 
	// as in Chapter 2 ost tree; 
	for (int i = 0; i < n; ++i) // O(n log n) 
		tree.insert(A[i]);
	// O(log n) select
	cout << *tree.find_by_order(0) << "\n"; // 1-smallest = 2 
	cout << *tree.find_by_order(n-1) << "\n"; // 9-smallest/largest = 71 
	cout << *tree.find_by_order(4) << "\n"; // 5-smallest = 15 
	
	// O(log n) rank 
	cout << tree.order_of_key(2) << "\n"; // index 0 (rank 1) 
	cout << tree.order_of_key(71) << "\n"; // index 8 (rank 9) 
	cout << tree.order_of_key(15) << "\n"; // index 4 (rank 5) 
	return 0; 
}

my solution

#include <bits/stdc++.h>

#include <bits/extc++.h>

using namespace std;

using namespace __gnu_pbds;

typedef tree<pair<pair<int, int>, int>, null_type, greater<pair<pair<int, int>, int>>, rb_tree_tag, 
            tree_order_statistics_node_update> ost;

int main() {
    int n, m, i, b;
    scanf("%d %d", &n, &m);
    
    ost tree;
    unordered_map<int, pair<int, int>> mp;

    for (int i = 1; i <= n; i++) {
        tree.insert({{0, 0}, -i});
        mp[i] = {0, 0};
    }

    while (m--) {
        scanf("%d %d", &i, &b);
        tree.erase({mp[i], -i});
        mp[i] = {mp[i].first + 1, mp[i].second - b};
        tree.insert({mp[i], -i});
        printf("%d\n", tree.order_of_key({mp[1], 1}) + 1);
    }
}