sqrt double Algorithm

The sqrt double algorithm is a powerful method for searching in a graph or tree structure, utilizing the square root of the size of the structure as its main parameter to achieve an efficient balance between time and space complexity. It is particularly useful in scenarios where the graph is very large or the structure is dynamically changing, and traditional search algorithms like breadth-first search (BFS) or depth-first search (DFS) may not be efficient enough. The fundamental idea of the sqrt double algorithm is to divide the entire structure into smaller groups or blocks, each containing approximately the square root of the total number of nodes, and then performing a two-level search within the blocks and between the blocks. In the first level, the algorithm preprocesses the given structure by calculating the shortest distances between all pairs of nodes within each block. This is typically done using a standard shortest-path algorithm like Floyd-Warshall, and the results are stored in a table for quick look-up during the search phase. In the second level, the algorithm computes the shortest distances between the entry and exit nodes of the different blocks, which can be done efficiently by leveraging the precomputed distances from the first level. Now, when a query for the shortest distance between two nodes is made, the algorithm can efficiently answer it by combining the precomputed distances within and between the relevant blocks. This two-level approach significantly reduces the time complexity compared to classical search algorithms while maintaining a relatively low space complexity, making the sqrt double algorithm a highly effective technique for large-scale or dynamic graph searches.
#include <iostream>
#include <cassert>

/* Calculate the square root of any 
number in O(logn) time, 
with precision fixed */

double Sqrt(double x) {
    if ( x > 0 && x < 1 ) {
        return 1/Sqrt(1/x);
    }
    double l = 0, r = x;
    /* Epsilon is the precision. 
    A great precision is 
    between 1e-7 and 1e-12.
    double epsilon = 1e-12;
    */
    double epsilon = 1e-12;
    while ( l <= r ) {
        double mid = (l + r) / 2;
        if ( mid * mid > x ) {
            r = mid;
        } else {
            if ( x - mid * mid < epsilon ) {
                return mid;
            }
            l = mid;
        }
    }
    return -1;
}
int main() {
  double n{};
  std::cin >> n;
  assert(n >= 0);
  // Change this line for a better precision
  std::cout.precision(12);
  std::cout << std::fixed << Sqrt(n);
}

LANGUAGE:

DARK MODE: