HardCode Blog

website·Indexed 30 days ago

https://hardcode-blog.vercel.app/en-US

A modern blog platform featuring a Neo-Brutalism design aesthetic, focusing on competitive programming, algorithm analysis, and C++. Content covers topics such as time complexity (Big O), the Euclidean Algorithm, 1D Prefix Sums, graph representation, and STL containers like Vector.

Tokens
8.1K
Snippets
40
Records
65
Agent score
75%

What's inside HardCode Blog

  1. HardCode Blog Technical Stack Overview

    HardCode Blog is a modern blog platform utilizing a Neo-Brutalism design aesthetic. It is built for high performance using Static Site Generation (SSG) and supports multi-language content (English and Chinese).
  2. Understand Competitive Programming contest tracks

    Competitive programming contests generally fall into three categories based on the target audience and format:

    1. Olympiad in Informatics (OI): Targeted at middle and high school students (e.g., NOIP, CSP, IOI). These typically last 3–5 hours and often use partial scoring based on the number of test cases passed.
    2. ICPC-style (Collegiate Programming Contest): Targeted at university students (e.g., ICPC, CCPC). Teams of three share one computer; rankings are based on the number of problems solved and penalty time. Results are binary (Accepted or Wrong Answer).
    3. Online Platforms: Open to everyone (e.g., Codeforces, LeetCode, AtCoder). These use rating systems to track skill and are ideal for daily practice.
  3. Implement a basic A+B problem in C++

    The 'A+B' problem is a fundamental exercise in reading input and printing a sum. In competitive programming, it is common to use a while loop to process multiple test cases until the End of File (EOF) is reached.
    #include <iostream> // input/output stream
    using namespace std;
     
    int main() {
        int a, b;
        // Process multiple test cases until EOF
        while (cin >> a >> b) {
            cout << a + b << endl;
        }
        return 0;
    }
  4. Manage Content with Markdown and Frontmatter

    HardCode Blog uses a file-based content management system. Articles are written in Markdown with metadata defined in YAML frontmatter. The processing pipeline is powered by remark and rehype.
  5. Implement 2D Difference Array for submatrix updates

    To add a value V to every element in a submatrix from (x1, y1) to (x2, y2), update four corners of the difference array D:

    1. D[x1][y1] += V
    2. D[x1][y2+1] -= V
    3. D[x2+1][y1] -= V
    4. D[x2+1][y2+1] += V

    After all updates are complete, the final matrix is produced by calculating the 2D prefix sum over D.

  6. Perform Discretization to map large values to ranks

    Discretization is used when the range of values is too large (e.g., 10^9) to be used as array indices, but the number of unique elements is small (e.g., 10^5). This process maps original values to their relative ranks (1, 2, ..., N).
    vector<int> a = {100000, 20, 9999999, 20};
    vector<int> b = a;
    
    // 1. Sort and remove duplicates
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());
    
    // 2. Find the rank of a specific value using lower_bound
    // rank is 1-based index
    int rank = lower_bound(b.begin(), b.end(), 9999999) - b.begin() + 1; // rank = 3
  7. Predict TLE using the 1-second operation rule

    In competitive programming (C++), modern judges can typically execute between 10^7 and 10^8 elementary operations per second.

    • Safe range: 3 to 5 × 10^7 operations.
    • Extreme limit: 2 to 4 × 10^8 operations (may still Time Limit Exceeded (TLE) due to constant factors).

    To determine if an algorithm will TLE: plug the maximum input size N into the Big O formula. If the result significantly exceeds 10^8, the algorithm is too slow.

  8. Estimate space complexity and avoid Memory Limit Exceeded (MLE)

    Estimate memory usage based on array size and data type. Common limits are 128MB or 256MB (256 MB ≈ 2.5 × 10^8 bytes).

    • char: 1 byte
    • int: 4 bytes
    • long long: 8 bytes

    Example: An int a[10^8] array uses 400 MB, which will likely trigger MLE on a 256MB limit.

    Critical Implementation Detail: Declare large arrays in the global scope. Local arrays are allocated on the stack, which has a very small limit (a few megabytes) and will cause a stack overflow for large allocations.

  9. Implement Topological Sort using Kahn's Algorithm

    Topological sorting is used to order tasks based on dependencies and applies only to Directed Acyclic Graphs (DAGs). If a cycle exists, no topological order is possible.

    Kahn's Algorithm Process:

    1. Calculate the indegree (number of incoming edges) for every node.
    2. Push all nodes with an indegree of 0 into a queue.
    3. While the queue is not empty:
      • Pop node u and add it to the result list.
      • For each neighbor v of u, decrement in_degree[v].
      • If in_degree[v] becomes 0, push v into the queue.
    4. If the result list contains all n nodes, the order is valid; otherwise, the graph contains a cycle.
    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;
     
    int n, m;
    vector<int> adj[10005];
    int in_degree[10005];
    vector<int> result;
     
    int main() {
        cin >> n >> m;
        for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            adj[u].push_back(v);
            in_degree[v]++;
        }
     
        queue<int> q;
        for (int i = 1; i <= n; i++) {
            if (in_degree[i] == 0) q.push(i);
        }
     
        while (!q.empty()) {
            int u = q.front(); q.pop();
            result.push_back(u);
            for (int v : adj[u]) {
                in_degree[v]--;
                if (in_degree[v] == 0) q.push(v);
            }
        }
     
        if (result.size() == n) {
            // output result
        } else {
            cout << "Cycle detected; no topological order" << endl;
        }
        return 0;
    }
  10. Apply common bitwise hacks for parity and uniqueness

    Bitwise operations can be used to efficiently check parity or find unique elements in a dataset.
    // Check parity
    if (x & 1) { /* x is odd */ }
    if (!(x & 1)) { /* x is even */ }
    
    // Swap two variables without a temporary variable
    a ^= b;
    b ^= a;
    a ^= b;
    
    // Find the lone number in an array where all others appear twice
    int lone = 0;
    for (int num : array) { lone ^= num; }
    // Result: lone contains the unique element because a ^ b ^ a = b
  11. Choose an IDE for competitive programming

    Depending on your goals and environment, choose one of the following IDEs:

    • Visual Studio Code (Recommended): Best for general use and engineering. Recommended extensions include C/C++ (Microsoft), C/C++ Compile Run, and Competitive Programming Helper (cph) for automating test case execution.
    • Dev-C++: Recommended for students preparing for exams (like CSP-J/S or NOIP) where outdated machines may only provide this IDE.
    • CP Editor: A specialized tool for purists that provides a side-by-side code and I/O layout with one-click submissions to Codeforces.
  12. Use Opposing Pointers for sorted array sums

    To find two numbers in a sorted array that sum to a specific target in O(N) time, use two pointers: one at the start (L) and one at the end (R). If the current sum is too high, decrement R to decrease the sum; if it is too low, increment L to increase the sum.