# Pre Processing

Building a prefix sum is a form of pre-processing. What are other forms of pre-processing?

Sorting: Sorting the input data to make it easier to access elements in a specific order. This can simplify binary searches and the identification of duplicates.

Data Transformation: Converting data into another format that is easier to handle. For example, converting all strings to lower or uppercase for string matching problems.

Hashing: Using hash tables to store data for quick look-up. This is often done to achieve constant-time access for elements.

Frequency Count: Counting the occurrence of each element in a set and storing these counts in an array or map. This is useful in array manipulation problems or string manipulation tasks.

Graph Construction: Preprocessing nodes and edges to create a graph representation from the given data. This is necessary for graph algorithms like shortest path or network flow.

Dynamic Programming Table Initialization: Initializing a DP table based on base cases. This can be considered a pre-processing step for dynamic programming solutions.

Segment Tree or Fenwick Tree Construction: Building a data structure that allows for efficient range queries and updates. Useful for problems involving cumulative statistics.

Conversion to Suffix Array or Trie: For string-based problems, transforming the string into a more searchable data structure like a suffix array or trie.

Decomposition: Breaking down complex structures like trees or graphs into simpler components for easier analysis.

Calculating Factorials or Powers: Precomputing factorials, square roots, or power terms that will be used repeatedly in the calculations.

Caching: Pre-storing results of expensive function calls can sometimes be considered a form of pre-processing, particularly if the cache is built up-front.

Geometric Preprocessing: In computational geometry problems, calculating and storing things like convex hulls or nearest neighbors in advance.

Each form of pre-processing aims to simplify the problem-solving steps that follow, generally by making data easier to navigate or by optimizing time complexity.