差分和前綴和

差分和前綴和的原理、用法和區別。

前綴和(Prefix Sum)

核心思想:預處理數組的前綴和,快速回答「區間和查詢」
適用場景:數組靜態(更新少、查詢多),需要頻繁計算任意區間的和

1. 定義與構建

對于原數組 ?a[0...n-1]?,前綴和數組 ?preSum??滿足:
preSum[i] = a[0] + a[1] + ... + a[i-1]?
(?preSum[0] = 0?,方便邊界計算)

構建代碼:

vector<long long> buildPreSum(vector<int>& a) {
int n = a.size();
vector<long long> preSum(n + 1, 0);
for (int i = 0; i < n; ++i) {
preSum[i + 1] = preSum[i] + a[i];
}
return preSum;
}

2. 核心作用:O(1) 區間和查詢

原數組區間 ?[l, r]?(閉區間)的和為:
sum(l, r) = preSum[r + 1] - preSum[l]?

示例:
原數組 ?a = [1, 2, 3, 4]?,則 ?preSum = [0, 1, 3, 6, 10]?
查詢 ?a[1..3]?(元素 ?2,3,4?)的和:?preSum[4] - preSum[1] = 10 - 1 = 9?

差分(Difference Array)

核心思想:預處理差分數組,快速執行「區間更新」
適用場景:數組動態(更新多、查詢少),需要頻繁對區間進行加減操作

1. 定義與構建對于原數組 ?

a[0...n-1]?,差分數組 ?diff??滿足:
diff[i] = \begin{cases}?
a[0] & (i=0) \\
a[i] - a[i-1] & (i>0)?
\end{cases}?

構建代碼(直接初始化,或從原數組推導):

vector<int> buildDiff(vector<int>& a) {
int n = a.size();
vector<int> diff(n, 0);
diff[0] = a[0];
for (int i = 1; i < n; ++i) {
diff[i] = a[i] - a[i-1];
}
return diff;
}

2. 核心操作:O(1) 區間更新

對原數組 ?a??的區間 ?[l, r]??全部加 ?val?,只需操作差分數組:

diff[l] += val; ? ? ? ? ? // 起點 l 開始有增量
if (r + 1 < n) {
diff[r + 1] -= val; ? // 終點 r+1 處取消增量(防止擴散到區間外)
}


原理:差分數組記錄的是「相鄰元素的變化量」。當通過前綴和還原原數組時,?diff[l] += val??的影響會傳遞到 ?a[l..n-1]?,而 ?diff[r+1] -= val??會抵消 ?r+1??之后的影響,最終只有 ?a[l..r]??被加上 ?val?。

3. 還原原數組(從差分 → 原數組)

對差分數組求前綴和,即可還原原數組:

vector<int> restoreArray(vector<int>& diff) {
int n = diff.size();
vector<int> a(n, 0);
a[0] = diff[0];
for (int i = 1; i < n; ++i) {
a[i] = a[i-1] + diff[i];
}
return a;
}

或更高效的原地操作(差分數組直接變原數組):

for (int i = 1; i < n; ++i) {
diff[i] += diff[i-1];
}
// 此時 diff 數組等價于原數組 a

前綴和 vs 差分:核心區別?

特性 前綴和(Prefix Sum) 差分(Difference Array)?
核心用途 快速查詢區間和(靜態數組) 快速執行區間更新(動態數組)?
操作對象 原數組 → 前綴和數組(預處理) 原數組 → 差分數組(預處理)?
時間復雜度 構建 O(n),查詢 O(1) 構建 O(n),區間更新 O(1),還原 O(n)?
典型場景 數組不變,頻繁查區間和(如 LeetCode 560) 數組常變,頻繁對區間加減(如 LeetCode 1109)?

綜合示例:前綴和 + 差分

題目:

1.?初始數組 ?a = [1, 2, 3, 4]?
2.?對區間 ?[1, 3]?(元素 ?2,3,4?)加 ?5?
3.?查詢最終數組的區間 ?[0, 2]?(元素 ?1,7,8?)的和

步驟 1:用差分執行區間更新

原數組 ?a = [1, 2, 3, 4]?,構建差分數組:

diff = [1, 1, 1, 1] ?// 因為 2-1=1, 3-2=1, 4-3=1


對區間 ?[1, 3]??加 ?5?:

diff[1] += 5; ? // diff[1] = 6
if (3+1 < 4) diff[4] -=5; ?// 數組長度 4,r+1=4 越界,無需操作


此時差分數組 ?diff = [1, 6, 1, 1]?

步驟 2:還原原數組(差分 → 原數組)

對 ?diff??求前綴和:

a[0] = 1 ?
a[1] = 1 + 6 = 7 ?
a[2] = 7 + 1 = 8 ?
a[3] = 8 + 1 = 9 ?


還原后數組 ?a = [1, 7, 8, 9]?

步驟 3:用前綴和查詢區間和

構建前綴和數組 ?preSum?:

preSum = [0, 1, 8, 16, 25] ?


查詢區間 ?[0, 2]??的和:

sum = preSum[3] - preSum[0] = 16 - 0 = 16

總結

- 前綴和是「區間和查詢」的優化工具,適合數組靜態、查詢頻繁的場景。
- 差分是「區間更新」的優化工具,適合數組動態、更新頻繁的場景。
- 兩者常配合使用:用差分處理更新,再用前綴和處理查詢,覆蓋更復雜的需求。

理解這兩個技巧的核心邏輯后,很多數組操作的題目(尤其是競賽題)都能迎刃而解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88228.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88228.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88228.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++并發編程-12. 用內存順序實現內存模型

前情回顧 前文我們介紹了六種內存順序&#xff0c;以及三種內存模型&#xff0c;本文通過代碼示例講解六種內存順序使用方法&#xff0c;并實現相應的內存模型。全局一致性模型同步模型(獲取和釋放)松散模型memory_order_seq_cst memory_order_seq_cst代表全局一致性順序&#…

AI測試革命:從智能缺陷檢測到自愈式測試框架的工業實踐

AI測試革命&#xff1a;從智能缺陷檢測到自愈式測試框架的工業實踐 希望對大家有用&#xff01; 目錄AI測試革命&#xff1a;從智能缺陷檢測到自愈式測試框架的工業實踐希望對大家有用&#xff01;一、傳統測試之殤&#xff1a;工業質檢的切膚之痛二、智能缺陷檢測系統架構1. …

二、深度學習——損失函數

二、損失函數損失函數定義&#xff1a;損失函數是用來衡量模型參數的質量的函數&#xff0c;衡量方式是比較網絡輸出和真實輸出的差異別名&#xff1a;損失函數&#xff08;loss function&#xff09;&#xff0c;代價函數&#xff08;cost function&#xff09;&#xff0c;目…

面向數據報的套接字通道技術詳解

數據報通道基礎 通道特性與創建方式 java.nio.channels.DatagramChannel類實例代表數據報通道&#xff0c;默認處于阻塞模式。通過configureBlocking(false)方法可將其配置為非阻塞模式。創建數據報通道需調用其靜態open()方法&#xff0c;若用于IP組播則需指定組播組的地址類型…

147.在 Vue3 中使用 OpenLayers 地圖上 ECharts 模擬飛機循環飛行

&#x1f9e9; 效果預覽 &#x1f447; 飛機從多個城市起飛并向其他城市飛行&#xff0c;動畫流暢&#xff0c;地圖可縮放拖拽&#xff1a; &#x1f4e6; 一、項目技術棧 技術用途Vue 3現代前端框架OpenLayers地圖底圖渲染ECharts ol-echarts飛機飛行動畫渲染ol-echarts將 …

OCR與PDF解析的區別

我們日常所接觸的文檔中&#xff0c;經常能碰到多語言混合的文檔。比如論文試卷、財報研報、跨國票據都含有多種語言和文字。要將文檔中的內容識別并提取務必需要使用到OCR技術&#xff0c;而傳統的OCR工具在處理這類型文檔的時候有局限性。早期的 OCR 系統識別精度有限&#x…

Java 單例類詳解:從基礎到高級,掌握線程安全與高效設計

作為一名Java開發工程師&#xff0c;你一定對**單例模式&#xff08;Singleton Pattern&#xff09;**不陌生。它是23種經典設計模式中最簡單也是最常用的一種&#xff0c;用于確保一個類在整個應用程序中只有一個實例存在。單例廣泛應用于系統配置、數據庫連接池、日志管理器、…

面向對象設計

你列出的這些屬于 C 高級開發中面向對象設計與架構設計的核心知識&#xff0c;也是面試高級工程師崗位必問的內容。下面我按順序&#xff0c;深入講解每一項概念、原理、用途&#xff0c;并穿插 C 示例。? 1. 設計原則&#xff08;SOLID&#xff09;SOLID 是面向對象設計的五大…

IntelliJ IDEA讓我的開發效率翻倍:從新手到高效開發者的進階之路

IntelliJ IDEA讓我的開發效率翻倍&#xff1a;從新手到高效開發者的進階之路 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 總有一行代碼&#xff0c;能點亮萬千星辰。 &#x1f50d; 在技術的宇宙中&#xff0c;我愿做永不停歇的探索者。 ? 用…

css sprites使用

CSS Sprites 是一種將多個小圖標或背景圖像合并到一個大圖中的技術。通過減少HTTP請求次數&#xff0c;可以顯著提高頁面加載速度。其核心原理是&#xff1a;通過設置元素的背景圖&#xff08;background-image&#xff09;為這個大圖&#xff0c;然后調整背景位置&#xff08;…

分布式爬蟲在電商平臺商品數據大規模采集中的技術應用

在電商平臺商品數據大規模采集場景中&#xff0c;分布式爬蟲憑借其高效、可擴展、抗風險的特性&#xff0c;成為突破單節點爬蟲性能瓶頸的核心技術方案。以下從技術架構、關鍵技術點、電商場景適配及挑戰應對四個維度&#xff0c;解析其具體應用&#xff1a;一、分布式爬蟲的核…

Linux的`if test`和`if [ ]中括號`的取反語法比較 筆記250709

Linux的if test和if 中括號的取反語法比較 筆記250709 Linux的 test命令&#xff08;或等價中括號寫法 [空格expression空格]&#xff09;的用法詳解. 筆記250709 四種取反語法: if ! test -e xxx ;then... 和 if test ! -e xxx ;then... 和 if ! [ -e xxx ] ;then... 和 if …

記錄使用ubuntu16.04編譯aosp(android8.1與10)遇到的問題

一、前言&#xff1a; 本來打算用wsl來編譯AOSP&#xff0c;但是折騰了好幾天&#xff0c;以失敗告終。后來使用vmware反而成功了。 本篇同樣會把wsl遇到的問題與嘗試記錄下來。 環境&#xff1a;vmware ubuntu16.04。 為什么會使用ubuntu16.04呢&#xff0c;因為在公司有一…

hiredis window之RFDMap

簡介 RFDMap用于將socket分配映射成連續的文件描述符&#xff0c;同時管理回收的文件描述符&#xff0c;因為ae構架中管理fd與對應事件處理器使用的是數據&#xff0c;fd作為數組下標 結構 #mermaid-svg-zQz2LTrKRi0LQTII {font-family:"trebuchet ms",verdana,arial…

RustFS一款Rust 驅動的 高性能 分布式存儲系統

演示地址&#xff1a;https://play.rustfs.com/browser 訪問賬號&#xff08;默認 rustfsadmin&#xff09;。 訪問密鑰&#xff08;默認 rustfsadmin&#xff09;。 下載mc https://dl.min.io/client/mc/release可以直接在 Linux 系統上安裝 mc&#xff08;&#xff0c;然后訪…

微軟 Bluetooth LE Explorer 實用工具的詳細使用分析

微軟 Bluetooth LE Explorer 實用工具的詳細使用分析 文章目錄 微軟 **Bluetooth LE Explorer** 實用工具的詳細使用分析1. **工具定位與核心功能**2. **關鍵特性與更新**3. **使用場景示例**4. **系統要求與依賴**5. **與專業工具對比**6. **局限性**7. **實踐建議**結論以下是…

centos 7.6安裝mysql8

在 CentOS 7.6 上安裝 MySQL 8.0.42 的步驟如下&#xff0c;基于搜索結果中的最新信息&#xff1a; 下載 MySQL 8.0.42 安裝包 https://dev.mysql.com/downloads/mysql/從 MySQL 官方網站下載 mysql-8.0.42-1.el7.x86_64.rpm-bundle.tar 文件&#xff1a; 官方下載地址&#xf…

CentOS7更換阿里云yum源

問題&#xff1a;剛剛在本地安裝了CentOS7虛擬機&#xff0c;使用yum安裝vim軟件時&#xff08;最小化安裝只有vi沒有vim&#xff09;出現下面的報錯原因 &#xff1a;CentOS7 已于2024-6-30停止維護&#xff0c;官方鏡像源已不可用&#xff0c;可以更換為阿里云鏡像源解決&…

UE5內置插件 AnimToTexture 簡單入門

開啟插件 首先安裝插件&#xff0c;然后重啟。打開顯示插件內容我們就可以找到插件自帶的轉換內容將骨骼網格體轉換為頂點動畫有兩種方式&#xff1a; 最簡單的記錄每個頂點的位置然后通過切換拾取顏色偏移實現記錄骨骼的變換&#xff0c;然后通過貼圖去修改骨骼位置計算 這兩種…

如何搭建Appium環境?

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快1、安裝Java Development Kit&#xff08;JDK&#xff09;前往Oracle官網下載JDK。在https://www.oracle.com/java/technologies/javase-jdk11-downloads.html 找到…