Square Root Decomposition in Cache Optimisation

Revision en2, by Tyx2019, 2026-05-25 04:39:39

Introduction

This last weekend, I took part in the Southeast Asia Team Selection Test (SEATST). On day $$$1$$$, to grab a $$$28$$$ point subtask, I used a interesting trick involving cache-optimisation and square root decomposition that I thought was cool, so naturally I am writing my first CF blog to talk about it.

The Problem

Suppose we have an array of $$$N$$$ vectors, $$$V_1$$$ to $$$V_N$$$, and we wish to perform $$$Q$$$ insertion operations of the form $$$(x, y)$$$, where we insert the value $$$y$$$ to the back of vector $$$V_x$$$. For instance, you might want to do this for a counting sort if the log factor from sorting is too large.

For the rest of this blog, we shall assume $$$N=10^6, Q=10^8$$$.

The naive solution

Below is the code I used for testing the naive solution. ~~~~~

include <bits/stdc++.h>

using namespace std; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int N = 1e6; const int Q = 1e8; vector V[N]; main(){
int x, y; for(int i=0;i<Q;i++){ x = rng() % N; y = rng(); V[x].push_back(y); } } ~~~~~ For the other pieces of code in this blog I will not include the boilerplate (i.e. everything outside of main).

Of course we need a control to see how much time generating random numbers took. Below is the control ~~~~~ main(){
int x, y; for(int i=0;i<Q;i++){ x = rng() % N; y = rng(); } } ~~~~~

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en4 English Tyx2019 2026-05-25 04:54:00 0 (published)
en3 English Tyx2019 2026-05-25 04:53:37 1218 Tiny change: ' control\n~~~~~\nm' -> ' control\n\n~~~~~\nm'
en2 English Tyx2019 2026-05-25 04:39:39 1157
en1 English Tyx2019 2026-05-25 04:08:40 382 Initial revision (saved to drafts)