<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 稀疏表 > 原文: [https://www.geeksforgeeks.org/sparse-table/](https://www.geeksforgeeks.org/sparse-table/) 我們已經在[范圍最小查詢(平方根分解和稀疏表)](https://www.geeksforgeeks.org/range-minimum-query-for-static-array/)中簡要討論了稀疏表。 稀疏表概念用于對一組靜態數據進行快速查詢(元素不變)。 它進行預處理,以便可以有效地回答查詢。 示例問題 1:范圍最小查詢 我們有一個數組`arr[0 ... n-1]`。 我們需要有效地找到從索引`L`(查詢開始)到`R`(查詢結束)的最小值,其中`0 <= L <= R <= n-1`。 考慮存在許多范圍查詢的情況。 **示例**: ``` Input: arr[] = {7, 2, 3, 0, 5, 10, 3, 12, 18}; query[] = [0, 4], [4, 7], [7, 8] Output: Minimum of [0, 4] is 0 Minimum of [4, 7] is 3 Minimum of [7, 8] is 12 ``` 這個想法是預先計算所有大小為`2^j`的子數組的最小值,其中`j`從 0 到`log n`變化。 我們進行表`lookup[i][j]`的查找,使`lookup[i][j]`包含從`i`開始且范圍為`2^j`的最小值。 例如,`lookup[0][3]`包含范圍為`[0, 7]`的最小值(從 0 開始且大小為`2^3`) **如何填充此查找表或稀疏表?** 這個想法很簡單,使用以前計算的值以自下而上的方式填充。 我們使用 2 的較低乘方的值計算 2 的當前乘方的范圍。 例如,要找到范圍`[0, 7]`的最小值(范圍大小是 3 的冪),我們可以使用以下兩個最小值。 a)范圍`[0, 3]`的最小值(范圍大小是 2 的冪) b)范圍`[4, 7]`的最小值(范圍大小是 2 的冪) 根據上面的示例,下面是公式, ``` // Minimum of single element subarrays is same // as the only element. lookup[i][0] = arr[i] // If lookup[0][2] <= lookup[4][2], // then lookup[0][3] = lookup[0][2] If lookup[i][j-1] <= lookup[i+2j-1-1][j-1] lookup[i][j] = lookup[i][j-1] // If lookup[0][2] > lookup[4][2], // then lookup[0][3] = lookup[4][2] Else lookup[i][j] = lookup[i+2j-1-1][j-1] ``` ![](https://img.kancloud.cn/2c/4b/2c4b3ad745105d175b4955a455ca9d80_488x295.png) 對于任意范圍`[L, R]`,我們需要使用 2 的冪的范圍。想法是使用 2 的最接近的冪。我們總是需要最多進行一次比較(比較兩個是 2 的冪的范圍的最小值。 一個范圍以`L`開頭,以“`L +`最近的 2 的冪”結尾。 另一個范圍以`R`結束,并以“`R – `最接近的 2 的冪`+ 1`”開頭。 例如,如果給定范圍是`(2, 10)`,我們比較兩個范圍`(2, 9)`和`(3, 10)`中的最小值。 Based on above example, below is formula, ``` // For (2, 10), j = floor(Log<sub>2</sub>(10-2+1)) = 3 j = floor(Log(R-L+1)) // If lookup[0][3] <= lookup[3][3], // then min(2, 10) = lookup[0][3] If lookup[L][j] <= lookup[R-(int)pow(2, j)+1][j] min(L, R) = lookup[L][j] // If lookup[0][3] > arr[lookup[3][3], // then min(2, 10) = lookup[3][3] Else min(L, R) = lookup[i+2j-1-1][j-1] ``` 由于我們只進行一次比較,因此查詢的時間復雜度為`O(1)`。 以下是上述想法的實現。 ## C++ ```cpp // C++ program to do range minimum query // using sparse table #include <bits/stdc++.h> using namespace std; #define MAX 500 // lookup[i][j] is going to store minimum // value in arr[i..j]. Ideally lookup table // size should not be fixed and should be // determined using n Log n. It is kept // constant to keep code simple. int lookup[MAX][MAX]; // Fills lookup array lookup[][] in bottom up manner. void buildSparseTable(int arr[], int n) { ????// Initialize M for the intervals with length 1 ????for (int i = 0; i < n; i++) ????????lookup[i][0] = arr[i]; ????// Compute values from smaller to bigger intervals ????for (int j = 1; (1 << j) <= n; j++) { ????????// Compute minimum value for all intervals with ????????// size 2^j ????????for (int i = 0; (i + (1 << j) - 1) < n; i++) { ????????????// For arr[2][10], we compare arr[lookup[0][7]]? ????????????// and arr[lookup[3][10]] ????????????if (lookup[i][j - 1] <? ????????????????????????lookup[i + (1 << (j - 1))][j - 1]) ????????????????lookup[i][j] = lookup[i][j - 1]; ????????????else ????????????????lookup[i][j] =? ?????????????????????????lookup[i + (1 << (j - 1))][j - 1]; ????????} ????} } // Returns minimum of arr[L..R] int query(int L, int R) { ????// Find highest power of 2 that is smaller ????// than or equal to count of elements in given ????// range. For [2, 10], j = 3 ????int j = (int)log2(R - L + 1); ????// Compute minimum of last 2^j elements with first ????// 2^j elements in range. ????// For [2, 10], we compare arr[lookup[0][3]] and ????// arr[lookup[3][3]], ????if (lookup[L][j] <= lookup[R - (1 << j) + 1][j]) ????????return lookup[L][j]; ????else ????????return lookup[R - (1 << j) + 1][j]; } // Driver program int main() { ????int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 }; ????int n = sizeof(a) / sizeof(a[0]); ????buildSparseTable(a, n); ????cout << query(0, 4) << endl; ????cout << query(4, 7) << endl; ????cout << query(7, 8) << endl; ????return 0; } ``` ## Java ```java // Java program to do range minimum query // using sparse table import java.io.*; class GFG { ????static int MAX =500; ????// lookup[i][j] is going to store minimum ????// value in arr[i..j]. Ideally lookup table ????// size should not be fixed and should be ????// determined using n Log n. It is kept ????// constant to keep code simple. ????static int [][]lookup = new int[MAX][MAX]; ????// Fills lookup array lookup[][] in bottom up manner. ????static void buildSparseTable(int arr[], int n) ????{ ????????// Initialize M for the intervals with length 1 ????????for (int i = 0; i < n; i++) ????????????lookup[i][0] = arr[i]; ????????// Compute values from smaller to bigger intervals ????????for (int j = 1; (1 << j) <= n; j++) { ????????????// Compute minimum value for all intervals with ????????????// size 2^j ????????????for (int i = 0; (i + (1 << j) - 1) < n; i++) { ????????????????// For arr[2][10], we compare arr[lookup[0][7]]? ????????????????// and arr[lookup[3][10]] ????????????????if (lookup[i][j - 1] <? ????????????????????????????lookup[i + (1 << (j - 1))][j - 1]) ????????????????????lookup[i][j] = lookup[i][j - 1]; ????????????????else ????????????????????lookup[i][j] =? ????????????????????????????lookup[i + (1 << (j - 1))][j - 1]; ????????????} ????????} ????} ????// Returns minimum of arr[L..R] ????static int query(int L, int R) ????{ ????????// Find highest power of 2 that is smaller ????????// than or equal to count of elements in given ????????// range. For [2, 10], j = 3 ????????int j = (int)Math.log(R - L + 1); ????????// Compute minimum of last 2^j elements with first ????????// 2^j elements in range. ????????// For [2, 10], we compare arr[lookup[0][3]] and ????????// arr[lookup[3][3]], ????????if (lookup[L][j] <= lookup[R - (1 << j) + 1][j]) ????????????return lookup[L][j]; ????????else ????????????return lookup[R - (1 << j) + 1][j]; ????} ????// Driver program ????public static void main (String[] args) ????{ ????????int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 }; ????????int n = a.length; ????????buildSparseTable(a, n); ????????System.out.println(query(0, 4)); ????????System.out.println(query(4, 7)); ????????System.out.println(query(7, 8)); ????} } // This code is contributed by vt_m. ``` ## Python3 ```py # Python3 program to do range minimum? # query using sparse table? import math # Fills lookup array lookup[][] in? # bottom up manner.? def buildSparseTable(arr, n): ????# Initialize M for the intervals ????# with length 1? ????for i in range(0, n):? ????????lookup[i][0] = arr[i]? ????j = 1 ????# Compute values from smaller to? ????# bigger intervals? ????while (1 << j) <= n:? ????????# Compute minimum value for all? ????????# intervals with size 2^j ????????i = 0 ????????while (i + (1 << j) - 1) < n:? ????????????# For arr[2][10], we compare arr[lookup[0][7]]? ????????????# and arr[lookup[3][10]]? ????????????if (lookup[i][j - 1] <? ????????????????lookup[i + (1 << (j - 1))][j - 1]):? ????????????????lookup[i][j] = lookup[i][j - 1]? ????????????else: ????????????????lookup[i][j] = \ ????????????????????????lookup[i + (1 << (j - 1))][j - 1]? ????????????i += 1 ????????j += 1???????? # Returns minimum of arr[L..R]? def query(L, R):? ????# Find highest power of 2 that is smaller? ????# than or equal to count of elements in? ????# given range. For [2, 10], j = 3? ????j = int(math.log2(R - L + 1))? ????# Compute minimum of last 2^j elements? ????# with first 2^j elements in range.? ????# For [2, 10], we compare arr[lookup[0][3]]? ????# and arr[lookup[3][3]],? ????if lookup[L][j] <= lookup[R - (1 << j) + 1][j]:? ????????return lookup[L][j]? ????else: ????????return lookup[R - (1 << j) + 1][j]? # Driver Code if __name__ == "__main__": ????a = [7, 2, 3, 0, 5, 10, 3, 12, 18]? ????n = len(a)? ????MAX = 500 ????# lookup[i][j] is going to store minimum? ????# value in arr[i..j]. Ideally lookup table? ????# size should not be fixed and should be? ????# determined using n Log n. It is kept? ????# constant to keep code simple.? ????lookup = [[0 for i in range(MAX)] ?????????????????for j in range(MAX)] ????buildSparseTable(a, n)? ????print(query(0, 4))? ????print(query(4, 7))? ????print(query(7, 8))? # This code is contributed by Rituraj Jain ``` ## C# ```cs // C# program to do range minimum query // using sparse table using System; public class GFG { ????static int MAX= 500; ????// lookup[i][j] is going to store minimum ????// value in arr[i..j]. Ideally lookup table ????// size should not be fixed and should be ????// determined using n Log n. It is kept ????// constant to keep code simple. ????static int [,]lookup = new int[MAX, MAX]; ????// Fills lookup array lookup[][] in bottom up manner. ????static void buildSparseTable(int []arr, int n) ????{ ????????// Initialize M for the intervals with length 1 ????????for (int i = 0; i < n; i++) ????????????lookup[i, 0] = arr[i]; ????????// Compute values from smaller to bigger intervals ????????for (int j = 1; (1 << j) <= n; j++) { ????????????// Compute minimum value for all intervals with ????????????// size 2^j ????????????for (int i = 0; (i + (1 << j) - 1) < n; i++) { ????????????????// For arr[2][10], we compare arr[lookup[0][7]]? ????????????????// and arr[lookup[3][10]] ????????????????if (lookup[i, j - 1] <? ????????????????????????????lookup[i + (1 << (j - 1)), j - 1]) ????????????????????lookup[i, j] = lookup[i, j - 1]; ????????????????else ????????????????????lookup[i, j] =? ????????????????????????????lookup[i + (1 << (j - 1)), j - 1]; ????????????} ????????} ????} ????// Returns minimum of arr[L..R] ????static int query(int L, int R) ????{ ????????// Find highest power of 2 that is smaller ????????// than or equal to count of elements in given ????????// range. For [2, 10], j = 3 ????????int j = (int)Math.Log(R - L + 1); ????????// Compute minimum of last 2^j elements with first ????????// 2^j elements in range. ????????// For [2, 10], we compare arr[lookup[0][3]] and ????????// arr[lookup[3][3]], ????????if (lookup[L, j] <= lookup[R - (1 << j) + 1, j]) ????????????return lookup[L, j]; ????????else ????????????return lookup[R - (1 << j) + 1, j]; ????} ????// Driver program ????static public void Main () ????{ ????????int []a = { 7, 2, 3, 0, 5, 10, 3, 12, 18 }; ????????int n = a.Length; ????????buildSparseTable(a, n); ????????Console.WriteLine(query(0, 4)); ????????Console.WriteLine(query(4, 7)); ????????Console.WriteLine(query(7, 8)); ????} } // This code is contributed by vt_m.? ``` Output: ``` Minimum of [0, 4] is 0 Minimum of [4, 7] is 3 Minimum of [7, 8] is 12 ``` 因此,稀疏表方法支持`O(1)`時間,`O(N log N)`預處理時間和`O(N log N)`空間的查詢操作。 示例問題 2:范圍 GCD 查詢 我們有一個數組`arr[0 ... n-1]`。 我們需要找到`L`和`R`范圍內的[最大公約數](https://www.geeksforgeeks.org/c-program-find-gcd-hcf-two-numbers/),其中 `0 <= L <= R <= n-1`。 考慮存在許多范圍查詢的情況,例如: ``` Input : arr[] = {2, 3, 5, 4, 6, 8} queries[] = {(0, 2), (3, 5), (2, 3)} Output : 1 2 1 ``` **我們使用 GCD 的以下屬性**: * GCD 函數是關聯的,`GCD(a, b, c)= GCD(GCD(a, b), c)= GCD(a, GCD(b, c))`,我們可以使用子范圍的 GCD 計算范圍的 GCD 。 * 如果我們多次采用重疊范圍的 GCD,那么它不會改變答案。 例如,`GCD(a, b, c)= GCD(GCD(a, b), GCD(b, c))`。 因此,像最小范圍查詢問題一樣,我們只需進行一次比較即可找到給定范圍的 GCD。 我們使用與上述相同的邏輯構建一個稀疏表。 建立稀疏表后,我們可以通過以 2 的冪打破給定范圍來找到所有 GCD,并將每張 GCD 加到當前答案中。 ## C++ ``` // C++ program to do range minimum query // using sparse table #include <bits/stdc++.h> using namespace std; #define MAX 500 // lookup[i][j] is going to store GCD of // arr[i..j]. Ideally lookup table // size should not be fixed and should be // determined using n Log n. It is kept // constant to keep code simple. int table[MAX][MAX]; // it builds sparse table. void buildSparseTable(int arr[], int n) { ????// GCD of single element is element itself ????for (int i = 0; i < n; i++) ????????table[i][0] = arr[i]; ????// Build sparse table ????for (int j = 1; j <= n; j++) ????????for (int i = 0; i <= n - (1 << j); i++) ????????????table[i][j] = __gcd(table[i][j - 1], ????????????????????table[i + (1 << (j - 1))][j - 1]); } // Returns GCD of arr[L..R] int query(int L, int R) { ????// Find highest power of 2 that is smaller ????// than or equal to count of elements in given ????// range.For [2, 10], j = 3 ????int j = (int)log2(R - L + 1); ????// Compute GCD of last 2^j elements with first ????// 2^j elements in range. ????// For [2, 10], we find GCD of arr[lookup[0][3]] and ????// arr[lookup[3][3]], ????return __gcd(table[L][j], table[R - (1 << j) + 1][j]); } // Driver program int main() { ????int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 }; ????int n = sizeof(a) / sizeof(a[0]); ????buildSparseTable(a, n); ????cout << query(0, 2) << endl; ????cout << query(1, 3) << endl; ????cout << query(4, 5) << endl; ????return 0; } ``` ## Java ```java // Java program to do range minimum query? // using sparse table? import java.util.*; class GFG {? static final int MAX = 500;? // lookup[i][j] is going to store GCD of? // arr[i..j]. Ideally lookup table? // size should not be fixed and should be? // determined using n Log n. It is kept? // constant to keep code simple.? static int [][]table = new int[MAX][MAX];? // it builds sparse table.? static void buildSparseTable(int arr[],? ?????????????????????????????int n)? {? ????// GCD of single element is ????// element itself? ????for (int i = 0; i < n; i++)? ????????table[i][0] = arr[i];? ????// Build sparse table? ????for (int j = 1; j <= n; j++)? ????????for (int i = 0; i <= n - (1 << j); i++)? ????????????table[i][j] = __gcd(table[i][j - 1],? ????????????????????????????????table[i + (1 << (j - 1))][j - 1]);? }? // Returns GCD of arr[L..R]? static int query(int L, int R)? {? ????// Find highest power of 2 that is? ????// smaller than or equal to count of? ????// elements in given range.For [2, 10], j = 3? ????int j = (int)Math.log(R - L + 1);? ????// Compute GCD of last 2^j elements? ????// with first 2^j elements in range.? ????// For [2, 10], we find GCD of? ????// arr[lookup[0][3]] and arr[lookup[3][3]],? ????return __gcd(table[L][j],? ?????????????????table[R - (1 << j) + 1][j]);? }? static int __gcd(int a, int b)? {? ????return b == 0 ? a : __gcd(b, a % b);????? } // Driver Code public static void main(String[] args)? {? ????int a[] = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };? ????int n = a.length;? ????buildSparseTable(a, n);? ????System.out.print(query(0, 2) + "\n");? ????System.out.print(query(1, 3) + "\n");? ????System.out.print(query(4, 5) + "\n");? }? }? // This code is contributed by PrinciRaj1992 ``` ## Python3 ```py # Python3 program to do range minimum? # query using sparse table? import math # Fills lookup array lookup[][] in? # bottom up manner.? def buildSparseTable(arr, n): ????# GCD of single element is element itself? ????for i in range(0, n):? ????????table[i][0] = arr[i]? ????# Build sparse table ????j = 1 ????while (1 << j) <= n:? ????????i = 0 ????????while i <= n - (1 << j):? ????????????table[i][j] = math.gcd(table[i][j - 1],? ???????????????????????????????????table[i + (1 << (j - 1))][j - 1]) ????????????i += 1 ????????j += 1 # Returns minimum of arr[L..R]? def query(L, R):? ????# Find highest power of 2 that is smaller? ????# than or equal to count of elements in? ????# given range. For [2, 10], j = 3? ????j = int(math.log2(R - L + 1))? ????# Compute GCD of last 2^j elements with? ????# first 2^j elements in range.? ????# For [2, 10], we find GCD of arr[lookup[0][3]]? ????# and arr[lookup[3][3]],? ????return math.gcd(table[L][j],? ????????????????????table[R - (1 << j) + 1][j]) # Driver Code? if __name__ == "__main__": ????a = [7, 2, 3, 0, 5, 10, 3, 12, 18]? ????n = len(a)? ????MAX = 500 ????# lookup[i][j] is going to store minimum? ????# value in arr[i..j]. Ideally lookup table? ????# size should not be fixed and should be? ????# determined using n Log n. It is kept? ????# constant to keep code simple.? ????table = [[0 for i in range(MAX)]? ????????????????for j in range(MAX)] ????buildSparseTable(a, n)? ????print(query(0, 2))? ????print(query(1, 3))? ????print(query(4, 5))? # This code is contributed by Rituraj Jain ``` ## C# ``` // C# program to do range minimum query? // using sparse table? using System; class GFG {? static readonly int MAX = 500;? // lookup[i,j] is going to store GCD of? // arr[i..j]. Ideally lookup table? // size should not be fixed and should be? // determined using n Log n. It is kept? // constant to keep code simple.? static int [,]table = new int[MAX, MAX];? // it builds sparse table.? static void buildSparseTable(int []arr,? ?????????????????????????????int n)? {? ????// GCD of single element is ????// element itself? ????for (int i = 0; i < n; i++)? ????????table[i, 0] = arr[i];? ????// Build sparse table? ????for (int j = 1; j <= n; j++)? ????????for (int i = 0; i <= n - (1 << j); i++)? ????????????table[i, j] = __gcd(table[i, j - 1],? ????????????????????????????????table[i + (1 << (j - 1)),? ?????????????????????????????????????????????????j - 1]);? }? // Returns GCD of arr[L..R]? static int query(int L, int R)? {? ????// Find highest power of 2 that is? ????// smaller than or equal to count of? ????// elements in given range. ????// For [2, 10], j = 3? ????int j = (int)Math.Log(R - L + 1);? ????// Compute GCD of last 2^j elements? ????// with first 2^j elements in range.? ????// For [2, 10], we find GCD of? ????// arr[lookup[0,3]] and arr[lookup[3,3]],? ????return __gcd(table[L, j],? ?????????????????table[R - (1 << j) + 1, j]);? }? static int __gcd(int a, int b)? {? ????return b == 0 ? a : __gcd(b, a % b);????? } // Driver Code public static void Main(String[] args)? {? ????int []a = { 7, 2, 3, 0, 5, 10, 3, 12, 18 };? ????int n = a.Length;? ????buildSparseTable(a, n);? ????Console.Write(query(0, 2) + "\n");? ????Console.Write(query(1, 3) + "\n");? ????Console.Write(query(4, 5) + "\n");? }? } // This code is contributed by Rajput-Ji ``` **輸出**: ``` 1 1 5 ``` * * * * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看