首要序列總和陣列是一個集合,它累積交錯元素的總和,直到達到特定的索引。這是一種廣泛應用於組合重構以優化時間複雜度的策略。樹狀數組,也被稱為二進位索引樹(BIT),是一種高效地更新元素並在對數時間複雜度內計算前序列總和的資料庫形式。
在本文中,我們將討論如何使用C 中的Fenwick Tree進行現代化改進,以從一個系列求和數組中揭示給定值的較小極限邊界,這個值被稱為K。
文法
語法定義了兩個函數,update和query,以及一個用於Fenwick樹的主函數,Fenwick樹是一種用於高效範圍查詢和更新操作的資料結構。 update函數接受一個索引idx,一個值val,數組的大小n,以及Fenwick樹數組BIT。它透過將val加入索引idx及其所有祖先的節點來更新Fenwick樹。 query函數接受一個索引idx和Fenwick樹數組BIT。它傳回從根節點到索引idx的節點的累積和。主函數宣告數組的大小n,前綴和數組arr,以及初始化為0的Fenwick樹數組BIT。
void update(int idx, int val, int n, int BIT[]) { while (idx <= n) { BIT[idx] += val; idx += (idx & -idx); } } int query(int idx, int BIT[]) { int sum = 0; while (idx > 0) { sum += BIT[idx]; idx -= (idx & -idx); } return sum; } // Driver code int main() { int n; int arr[n+1]; int BIT[n+1] = {0}; return 0; }
演算法
要確定帶有Fenwick樹更新的前綴和數組中K的最小值,請按照以下複雜的步驟進行 -
實例化大小為 n 1 的 Fenwick 樹 (BIT),將所有元素初始化為 0。
使用 update() 函數修改具有給定前綴和陣列的 Fenwick Tree。
在Fenwick樹上執行查詢以確定K的下界。從n的二進位表示中的最高有效位元開始迭代,直到最低有效位元。使用query()函數驗證目前前綴和是否小於或等於K。如果滿足此條件,將當前前綴和從K中減去,並更新索引以移動到下一個位元。如果不滿足條件,則在不更新索引的情況下移動到下一個位元。
遍歷完所有位元後,索引將表示前綴和陣列中 K 的下界。
輸出所得到的索引作為K的下界。
方法
方法1 − 在Fenwick樹上進行二分查找。在這種方法中,我們在Fenwick樹上執行二分查找以找到K的下界。
方法2 - 在Fenwick樹上進行帶有延遲傳播的二分查找。
方法 1
為了解決這個問題,我們首先將左指標和右指標分別設定為1和n(表示前綴和陣列的大小),然後採用二分查找策略來確定對應於小於或等於K的最大前綴和的索引i。然後,根據前綴和[i]的值是否小於或等於K,更新左指標或右指標的位置。
範例
這段程式碼的基本機制是利用了一種叫做 Fenwick Tree(也稱為 Binary Indexed Tree)的資料結構。它的作用是在前綴和數組中確定指定值 'k' 的下界。這是透過使用更新函數建立 Fenwick Tree 來實現的,該函數將前綴和數組中每個元素的值合併到 Fenwick Tree 的相應位置中。
findLowerBound 函數接著採用二分搜尋演算法,透過查詢函數來找出前綴和陣列中「k」的下界。此函數計算直至 Fenwick 樹中目前索引的值的累積和。最終,程式碼最終識別出前綴和陣列中「k」下界的索引,並將結果顯示到控制台。
#include <iostream> using namespace std; void update(int i, int v, int n, int b[]) { while (i <= n) { b[i] += v; i += (i & -i); } } int query(int i, int b[]) { int s = 0; while (i > 0) { s += b[i]; i -= (i & -i); } return s; } int findLowerBound(int k, int n, int p[], int b[]) { int l = 1, r = n, idx = 0; while (l <= r) { int m = (l + r) / 2; int msum = query(m, b); if (msum <= k) { idx = m; l = m + 1; } else { r = m - 1; } } return idx; } int main() { int n = 5; int p[] = {0, 1, 3, 6, 10, 15}; int b[n + 1] = {0}; for (int i = 1; i <= n; i++) { update(i, p[i], n, b); } int k = 10, idx; idx = findLowerBound(k, n, p, b); cout << "The lower bound of " << k << " is at index " << idx << " in the prefix sum array." << endl; return 0; }
輸出
The lower bound of 10 is at index 3 in the prefix sum array.
方法2
為了進一步優化 Fenwick 樹,可以採用一種稱為惰性傳播的技術。這種方法需要將對 Fenwick Tree 的更新推遲到實際需要時,從而減少更新次數並提高查詢過程的效率。
範例
程式碼提供了一種解決方案,用於在前綴和陣列中定位給定值K的下限。前綴和數組是一個數組,其中每個元素都是原始數組中從索引0到該索引的元素的總和。下限是前綴和陣列中第一個使得到該索引的元素總和等於或超過K的索引。此解決方案使用Fenwick樹資料結構和延遲傳播技術來增強解決方案的效率。程式碼包括修改Fenwick樹、計算前綴和和找出下限的函數。程式碼還初始化了前綴和數組、Fenwick樹和延遲傳播數組。最後,它輸出了前綴和數組中K的下限。
#include <iostream> #include <cstring> using namespace std; void update(int idx, int val, int n, int ft[], int lz[]) { while (idx <= n) ft[idx] += val, idx += (idx & -idx); } int getPrefixSum(int idx, int ft[]) { int sum = 0; while (idx > 0) sum += ft[idx], idx -= (idx & -idx); return sum; } int findLowerBound(int K, int n, int ps[], int ft[], int lz[]) { int l = 1, r = n, lb = 0; while (l <= r) { int m = (l + r) / 2, s = getPrefixSum(m, ft) + lz[m]; if (s <= K) lb = m, l = m + 1; else r = m - 1; } return lb; } int main() { int n = 5; int ps[] = {0, 1, 3, 6, 10, 15}; int ft[n + 1], lz[n + 1]; memset(ft, 0, sizeof(ft)); memset(lz, 0, sizeof(lz)); for (int i = 1; i <= n; i++) update(i, ps[i] - ps[i - 1], n, ft, lz); int K = 10; int lb = findLowerBound(K, n, ps, ft, lz); cout << "For the given array with size " << n << " and prefix sum array ["; for (int i = 1; i <= n; i++) { cout << ps[i]; if (i < n) cout << ", "; } cout << "], the lower bound of " << K << " is at index " << lb << " in the prefix sum array." << endl; return 0; }
輸出
For the given array with size 5 and prefix sum array [1, 3, 6, 10, 15], the lower bound of 10 is at index 4 in the prefix sum array.
結論
關於從精心設計的前綴和數組中挖掘難以捉摸的 K 值閾值的討論,並透過更新進行強化,利用 C 程式設計領域中巧妙的芬威克樹演算法。深入研究兩種高效方法的複雜性:Fenwick 樹上的二分搜尋和帶有惰性傳播的 Fenwick 樹上的二分搜尋。根據您的特定難題的特定要求和限制,仔細選擇最合適的方法。希望這能夠闡明這一難以捉摸的任務的概念化和實現,即利用 C 領域中 Fenwick 樹無與倫比的功能,從帶有更新的前綴和數組中找到 K 的下界。
以上是使用樹狀數組的前綴和數組更新,查詢K的下界的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C#和C 的学习曲线和开发者体验有显著差异。1)C#的学习曲线较平缓,适合快速开发和企业级应用。2)C 的学习曲线较陡峭,适用于高性能和低级控制的场景。

C#和C 在面向对象编程(OOP)中的实现方式和特性上有显著差异。1)C#的类定义和语法更为简洁,支持如LINQ等高级特性。2)C 提供更细粒度的控制,适用于系统编程和高性能需求。两者各有优势,选择应基于具体应用场景。

從XML轉換到C 並進行數據操作可以通過以下步驟實現:1)使用tinyxml2庫解析XML文件,2)將數據映射到C 的數據結構中,3)使用C 標準庫如std::vector進行數據操作。通過這些步驟,可以高效地處理和操作從XML轉換過來的數據。

C#使用自動垃圾回收機制,而C 採用手動內存管理。 1.C#的垃圾回收器自動管理內存,減少內存洩漏風險,但可能導致性能下降。 2.C 提供靈活的內存控制,適合需要精細管理的應用,但需謹慎處理以避免內存洩漏。

C 在現代編程中仍然具有重要相關性。 1)高性能和硬件直接操作能力使其在遊戲開發、嵌入式系統和高性能計算等領域佔據首選地位。 2)豐富的編程範式和現代特性如智能指針和模板編程增強了其靈活性和效率,儘管學習曲線陡峭,但其強大功能使其在今天的編程生態中依然重要。

C 學習者和開發者可以從StackOverflow、Reddit的r/cpp社區、Coursera和edX的課程、GitHub上的開源項目、專業諮詢服務以及CppCon等會議中獲得資源和支持。 1.StackOverflow提供技術問題的解答;2.Reddit的r/cpp社區分享最新資訊;3.Coursera和edX提供正式的C 課程;4.GitHub上的開源項目如LLVM和Boost提陞技能;5.專業諮詢服務如JetBrains和Perforce提供技術支持;6.CppCon等會議有助於職業

C#適合需要高開發效率和跨平台支持的項目,而C 適用於需要高性能和底層控制的應用。 1)C#簡化開發,提供垃圾回收和豐富類庫,適合企業級應用。 2)C 允許直接內存操作,適用於遊戲開發和高性能計算。

C 持續使用的理由包括其高性能、廣泛應用和不斷演進的特性。 1)高效性能:通過直接操作內存和硬件,C 在系統編程和高性能計算中表現出色。 2)廣泛應用:在遊戲開發、嵌入式系統等領域大放異彩。 3)不斷演進:自1983年發布以來,C 持續增加新特性,保持其競爭力。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用