藍橋杯之差分題型

一維差分

問題描述

給定一個長度為?nn?的序列?aa

再給定?mm?組操作,每次操作給定?33?個正整數?l,r,dl,r,d,表示對?al~ralr??中的所有數增加?dd

最終輸出操作結束后的序列?aa

Update:由于評測機過快,n,mn,m?于 2024-12-09 從?105105?加強至?2×1052×105,杜絕暴力通過本題。?

輸入格式

第一行輸入兩個正整數?n,mn,m。(1≤n,m≤2×1051≤n,m≤2×105)

第二行輸入?nn?個正整數?aiai?。(1≤i≤n,1≤ai≤1041≤in,1≤ai?≤104)。

接下來?mm?行,每行輸入?33?個正整數?l,r,dl,r,d。(1≤l≤r≤n,?104≤d≤1041≤lrn,?104≤d≤104)。

輸出格式

輸出?nn?個整數,表示操作結束后的序列?aa

樣例輸入

6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1

樣例輸出

3 4 5 3 4 2

思路解析

1.?輸入數據
  • 讀取數組的長度 n 和操作的次數 m。

  • 創建兩個數組:

    • a:存儲原始數組的值。

    • sum:差分數組,用于記錄每個位置的變化。

2.?構建差分數組
  • 遍歷數組 a,計算差分數組 sum

    sum[i]=a[i]?a[i?1]
    • 解釋

      • 差分數組 sum 的每個位置存儲了當前元素與前一個元素的差值。

      • 通過差分數組,可以高效地對區間進行加法操作。

3.?處理區間加法操作
  • 對于每次操作,指定區間 [l,r] 和值 tmp:

    • 在差分數組 sum 中:

      • sum[l] += \text{tmp}:表示從位置 l 開始的區間增加 tmp。

      • sum[r+1] -= \text{tmp}:表示在位置 r+1 之后的區間減去 tmp,以抵消前面的增加操作。

    • 注意:如果 r+1 超出數組范圍,則不需要減去 tmp。

4.?恢復原始數組
  • 遍歷差分數組 sum,恢復更新后的數組 a

    a[i]=a[i?1]+sum[i]
    • 解釋

      • 通過累加差分數組的值,可以恢復每個位置的最終值。

5.?輸出結果
  • 輸出更新后的數組 a

?代碼實現

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);// 讀取數組長度和操作次數int n = scan.nextInt();int m = scan.nextInt();// 創建數組存儲原始數組和差分數組int[] a = new int[n + 1];int[] sum = new int[n + 1];// 輸入數組并構建差分數組for (int i = 1; i <= n; i++) {a[i] = scan.nextInt();sum[i] = a[i] - a[i - 1];}// 處理區間加法操作for (int i = 1; i <= m; i++) {int l = scan.nextInt();int r = scan.nextInt();int tmp = scan.nextInt();// 對區間 [l, r] 進行更新sum[l] += tmp;if (r + 1 <= n) {sum[r + 1] -= tmp;}}// 恢復更新后的數組for (int i = 1; i <= n; i++) {a[i] = a[i - 1] + sum[i];System.out.print(a[i] + " ");}scan.close();}
}

總結

  1. 核心思路

    • 利用差分數組高效地處理區間加法操作。

    • 通過差分數組的累加恢復最終的數組。

  2. 關鍵步驟

    • 構建差分數組

      sum[i]=a[i]?a[i?1]
    • 處理區間加法

      sum[l]+=tmpsum[r+1]?=tmp(如果?r+1≤n)
    • 恢復數組

      a[i]=a[i?1]+sum[i]
  3. 優點

    • 時間復雜度:每次區間加法操作的時間復雜度為 O(1),恢復數組的時間復雜度為 O(n)。

    • 空間復雜度:額外空間復雜度為 O(n)。

二維差分

問題描述

給定一個?n×mn×m?大小的矩陣?AA。

給定?qq?組操作,每次操作為給定?55?個正整數?x1,y1,x2,y2,dx1?,y1?,x2?,y2?,d,Ax1,y1Ax1?,y1???是子矩陣左上角端點,Ax2,y2Ax2?,y2???是子矩陣右下角端點,你需要給其中每個元素都增加?dd。

輸出操作結束后的矩陣?AA。

輸入格式

第一行輸入?33?個正整數?n,m,qn,m,q。(1≤n,m≤103,1≤q≤1051≤n,m≤103,1≤q≤105)

接下來?nn?行每行輸入?mm?個整數,表示?Ai,jAi,j?。(?103≤Ai,j≤103,1≤i≤n,1≤j≤m)(?103≤Ai,j?≤103,1≤i≤n,1≤j≤m)

接下來?qq?行,每行輸入?55?個正整數?x1,y1,x2,y2,dx1?,y1?,x2?,y2?,d。(1≤x1≤x2≤n,1≤y1≤y2≤m,?103≤d≤103)(1≤x1?≤x2?≤n,1≤y1?≤y2?≤m,?103≤d≤103)

輸出格式

輸出?nn?行?mm?個整數,表示操作結束后的矩陣?AA。

樣例輸入

3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1

樣例輸出

2 3 4 1
4 3 4 1
2 2 2 2

思路解析

1.?輸入數據
  • 讀取矩陣的行數 n 和列數 m,以及操作的次數 q。

  • 創建兩個二維數組:

    • a:存儲原始矩陣的值。

    • sum:差分數組,用于記錄每個位置的變化。

2.?構建差分數組
  • 遍歷矩陣 a,計算差分數組 sum

    sum[i][j]=a[i][j]?a[i?1][j]?a[i][j?1]+a[i?1][j?1]
    • 解釋

      • 差分數組 sum 的每個位置存儲了當前元素與相鄰元素的差值。

      • 通過差分數組,可以高效地對區間進行加法操作。

3.?處理區間加法操作
  • 對于每次操作,指定區間 [x1,y1] 到 [x2,y2] 和值 tmp:

    • 在差分數組 sum 中:

      • sum[x1][y1] += \text{tmp}:表示從位置 [x1,y1] 開始的區間增加 tmp。

      • sum[x2+1][y1] -= \text{tmp}:表示在位置 [x2+1,y1] 之后的區間減去 tmp,以抵消前面的增加操作。

      • sum[x1][y2+1] -= \text{tmp}:表示在位置 [x1,y2+1] 之后的區間減去 tmp,以抵消前面的增加操作。

      • sum[x2+1][y2+1] += \text{tmp}:表示在位置 [x2+1,y2+1] 之后的區間加上 tmp,以抵消前面的減法操作。

    • 注意:如果某個位置超出矩陣范圍,則不需要進行操作。

4.?恢復原始矩陣
  • 遍歷差分數組 sum,恢復更新后的矩陣 a

    a[i][j]=a[i?1][j]+a[i][j?1]?a[i?1][j?1]+sum[i][j]
    • 解釋

      • 通過累加差分數組的值,可以恢復每個位置的最終值。

5.?輸出結果
  • 輸出更新后的矩陣 a

代碼實現

import java.util.*;public class Main {static final int N = 1000 + 10;static int[][] a = new int[N][N];static int[][] sum = new int[N][N];// 差分操作函數public static void f(int x1, int y1, int x2, int y2, int tmp) {sum[x1][y1] += tmp;sum[x2 + 1][y1] -= tmp;sum[x1][y2 + 1] -= tmp;sum[x2 + 1][y2 + 1] += tmp;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 讀取矩陣的行數、列數和操作次數int n = sc.nextInt();int m = sc.nextInt();int q = sc.nextInt();// 輸入矩陣并構建差分數組for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {a[i][j] = sc.nextInt();sum[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];}}// 處理區間加法操作while (q-- > 0) {int x1 = sc.nextInt();int y1 = sc.nextInt();int x2 = sc.nextInt();int y2 = sc.nextInt();int tmp = sc.nextInt();f(x1, y1, x2, y2, tmp);}// 恢復矩陣并輸出結果for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + sum[i][j];System.out.print(a[i][j] + " ");}System.out.println();}sc.close();}
}

總結

  1. 核心思路

    • 利用二維差分數組高效地處理區間加法操作。

    • 通過差分數組的累加恢復最終的矩陣。

  2. 關鍵步驟

    • 構建差分數組

      sum[i][j]=a[i][j]?a[i?1][j]?a[i][j?1]+a[i?1][j?1]
    • 處理區間加法

      sum[x1][y1]+=tmpsum[x2+1][y1]?=tmpsum[x1][y2+1]?=tmpsum[x2+1][y2+1]+=tmp
    • 恢復矩陣

      a[i][j]=a[i?1][j]+a[i][j?1]?a[i?1][j?1]+sum[i][j]
  3. 優點

    • 時間復雜度:每次區間加法操作的時間復雜度為 O(1),恢復矩陣的時間復雜度為 O(n×m)。

    • 空間復雜度:額外空間復雜度為 O(n×m)。

相關的習題練習

棋盤
問題描述

小藍擁有?n×nn×n?大小的棋盤,一開始棋盤上全都是白子。小藍進行了?mm?次操作,每次操作會將棋盤上某個范圍內的所有棋子的顏色取反(也就是白色棋子變為黑色,黑色棋子變為白色)。請輸出所有操作做完后棋盤上每個棋子的顏色。

輸入格式

輸入的第一行包含兩個整數?nn,mm,用一個空格分隔,表示棋盤大小與操作數。

接下來?mm?行每行包含四個整數?x1x1?,y1y1?,x2x2?,y2y2?,相鄰整數之間使用一個空格分隔,表示將在?x1x1??至?x2x2??行和?y1y1??至?y2y2??列中的棋子顏色取反。

輸出格式

輸出?nn?行,每行?nn?個?00?或?11?表示該位置棋子的顏色。如果是白色則輸出?00,否則輸出?11。

樣例輸入

3 3
1 1 2 2
2 2 3 3
1 1 3 3

樣例輸出

001
010
100

評測用例規模與約定

對于?3030% 的評測用例,n,m≤500n,m≤500?;

對于所有評測用例,1≤n,m≤20001≤n,m≤2000,1≤x1≤x2≤n1≤x1?≤x2?≤n,1≤y1≤y2≤m1≤y1?≤y2?≤m。

思路解析

1.?輸入數據
  • 讀取棋盤的大小 n 和操作的次數 m。

  • 創建兩個二維數組:

    • b:二維差分數組,用于記錄每次翻轉操作的影響。

    • s:二維前綴和數組,用于計算每個位置的翻轉次數。

2.?處理翻轉操作
  • 對于每次操作,指定矩形區域 [x1,y1] 到 [x2,y2]:

    • 在差分數組 b 中:

      • b[x1][y1] += 1:表示從位置 [x1,y1] 開始的區域增加一次翻轉。

      • b[x2 + 1][y1] -= 1:表示在位置 [x2+1,y1] 之后的區域減去一次翻轉,以抵消前面的增加操作。

      • b[x1][y2 + 1] -= 1:表示在位置 [x1,y2+1] 之后的區域減去一次翻轉,以抵消前面的增加操作。

      • b[x2 + 1][y2 + 1] += 1:表示在位置 [x2+1,y2+1] 之后的區域加上一次翻轉,以抵消前面的減法操作。

    • 注意:如果某個位置超出棋盤范圍,則不需要進行操作。

3.?計算二維前綴和
  • 遍歷差分數組 b,計算每個位置的翻轉次數:

    s[i][j]=b[i][j]+s[i?1][j]+s[i][j?1]?s[i?1][j?1]
    • 解釋

      • 通過累加差分數組的值,可以計算每個位置的翻轉次數。

4.?確定最終狀態
  • 遍歷二維前綴和數組 s,判斷每個位置的翻轉次數的奇偶性:

    • 如果翻轉次數為奇數,表示該位置的顏色被翻轉了奇數次,最終狀態為白色(假設初始狀態為黑色)。

    • 如果翻轉次數為偶數,表示該位置的顏色被翻轉了偶數次,最終狀態為黑色。

    • 輸出每個位置的最終狀態。

代碼實現

import java.util.Scanner;public class Main {static final int N = 2000 + 10; // 假設最大值為2000,加上一些緩沖static int[][] b = new int[N][N]; // 二維差分數組,用于記錄翻轉操作的影響static int[][] s = new int[N][N]; // 二維前綴和數組,用于計算每個位置的翻轉次數static int n, m;public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 讀取輸入n = sc.nextInt(); // 棋盤大小m = sc.nextInt(); // 操作次數// 處理每個翻轉操作while (m-- > 0) {int x1 = sc.nextInt();int y1 = sc.nextInt();int x2 = sc.nextInt();int y2 = sc.nextInt();// 更新二維差分數組 bb[x1][y1] += 1;if (x2 + 1 < N) b[x2 + 1][y1] -= 1;if (y2 + 1 < N) b[x1][y2 + 1] -= 1;if (x2 + 1 < N && y2 + 1 < N) b[x2 + 1][y2 + 1] += 1;}// 計算二維前綴和并確定最終狀態for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {// 計算二維前綴和s[i][j] = b[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];// 判斷翻轉次數的奇偶性,確定最終顏色System.out.print(s[i][j] % 2);}System.out.println(); // 換行}sc.close(); // 關閉輸入流}
}

總結

  1. 核心思路

    • 利用二維差分數組高效地處理區間翻轉操作。

    • 通過二維前綴和數組計算每個位置的翻轉次數,判斷奇偶性確定最終狀態。

  2. 關鍵步驟

    • 處理翻轉操作

      b[x1][y1]+=1b[x2+1][y1]?=1b[x1][y2+1]?=1b[x2+1][y2+1]+=1
    • 計算二維前綴和

      s[i][j]=b[i][j]+s[i?1][j]+s[i][j?1]?s[i?1][j?1]
    • 確定最終狀態

      最終狀態=s[i][j]%2
  3. 優點

    • 時間復雜度:每次翻轉操作的時間復雜度為 O(1),計算前綴和的時間復雜度為 O(n2)。

    • 空間復雜度:額外空間復雜度為 O(n2)。

??自學藍橋杯筆記,希望我們可以一起學習!

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

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

相關文章

深入剖析 C/S 與 B/S 架構及網絡通信基礎

目錄 C/S 架構詳解? 概念與示例? 優點? B/S 架構詳解? 概念與示例? 優勢? 缺點? C/S 與 B/S 的區別? 架構組成? 使用場景? 開發和維護? 安全性? 網絡通信基礎? IP 地址? MAC&#xff08;物理地址&#xff09;? 端口? 路由器? 網關? 子網掩…

常見免殺框架的使用(3款)---【AniYaGUI1.2.0、AV_Evasion_Tool掩日、FoxBypass_V1.0】

一、AniYaGUI1.2.0免殺框架 環境&#xff1a;虛擬機Win10 、云服務器 工具&#xff1a;Xshell、CobaltStrike 項目下載地址&#xff1a; https://github.com/piiperxyz/AniYa 1. 安裝Go語言環境 確保Win10虛擬機安裝 Golang 且環境變量中包含 go 否則?法編譯&#xff08;注…

Apache HTTPD 換行解析漏洞

漏洞介紹 CVE-2017-15715 Apache HTTPD 是一個廣泛使用的 HTTP 服務器&#xff0c;可以通過 mod_php 模塊來運行 PHP 網頁。在其 2.4.0 到 2.4.29 版本中存在一個解析漏洞&#xff0c;當文件名以 1.php\x0A 結尾時&#xff0c;該文件會被按照 PHP 文件進行解析&#xff0c;這…

常用開發環境/工具版本選擇(持續更新中)

操作系統&#xff1a;Ubuntu Server Version&#xff08;LTS&#xff09;Latest Sub VerRelease Time24.04(Noble Numbat)24.04.22025-02-1622.04(Jammy Jellyfish)22.04.52024-09-1120.04(Focal Fossa)20.04.62023-03-1418.04(Bionic Beaver)18.04.62021-09-1516.04.7(Xenial…

STM32 認識STM32

目錄 什么是嵌入式&#xff1f; 認識STM32單片機 開發環境安裝 安裝開發環境 開發板資源介紹 單片機開發模式 創建工程的方式 燒錄STM32程序 什么是嵌入式&#xff1f; 1.智能手環項目 主要功能有&#xff1a; 彩色觸摸屏 顯示時間 健康信息&#xff1a;心率&#…

C#核心筆記——(六)框架基礎

我們在編程時所需的許多核心功能并不是由C#語言提供的,而是由.NET Framework中的類型提供的。本節我們將介紹Framework在基礎編程任務(例如虛的等值比較、順序比較以及類型轉換)中的作用。我們還會介紹Framework中的基本類型,例如String、DateTime和Enum. 本章中的絕大部分…

AI——K近鄰算法

文章目錄 一、什么是K近鄰算法二、KNN算法流程總結三、Scikit-learn工具1、安裝2、導入3、簡單使用 三、距離度量1、歐式距離2、曼哈頓距離3、切比雪夫距離4、閔可夫斯基距離5、K值的選擇6、KD樹 一、什么是K近鄰算法 如果一個樣本在特征空間中的k個最相似&#xff08;即特征空…

transient關鍵字深度解析

Java transient 關鍵字深度解析 transient(意思:瞬時的,瞬間的) 1. 核心概念 (1) 基本定義 作用:標記字段不參與序列化 適用場景: 敏感數據(如密碼、密鑰) 臨時計算字段 依賴運行時環境的字段(如Thread對象) (2) 語法示例 java public class User implements Se…

信刻電子檔案藍光光盤刻錄安全檢測長期歸檔

信刻一直致力于為檔案館、各行業檔案部門&#xff0c;提供跨網數據交換、電子檔案數據磁光異質備份歸檔解決方案。所研制的電子檔案光盤智能長期歸檔系統&#xff0c;滿足國產環境下”刻、管、存、檢、用”全生命周期管理應用需求&#xff0c;能夠提供一份離線歸檔、一份近線存…

Word 中“母版頁”的等效機制

Word 和 PowerPoint 不太一樣——**Word 實際上沒有像 PowerPoint 那樣的“母版頁&#xff08;Master Page&#xff09;”**功能。但它有1個和“母版頁”功能類似的東西&#xff0c;可能造成你看到的“校徽自動出現在每一頁”的現象&#xff1a; ? Word 中“母版頁”的等效機制…

Go:反射

為什么使用反射 在編程中&#xff0c;有時需編寫函數統一處理多種值類型 &#xff0c;這些類型可能無法共享同一接口、布局未知&#xff0c;甚至在設計函數時還不存在 。 func Sprint(x interface{}) string {type stringer interface {String() string}switch x : x.(type) …

SS25001-多路復用開關板

1 概述 1.1 簡介 多路復用開關板是使用信號繼電器實現2線制的多路復用開關板卡&#xff1b;多路復用開關是一種可以將一個輸入連接到多個輸出或一個輸出連接到多個輸入的拓撲結構。這種拓撲通常用于掃描&#xff0c;適合將一系列通道自動連接到公共線路的的設備。多路復用開…

vue3 nprogress 使用

nprogress 介紹與作用 1.nprogress 是一個輕量級的進度條組件&#xff0c;主要用于在頁面加載或路由切換時顯示一個進度條&#xff0c;提升用戶體驗。它的原理是通過在頁面頂部創建一個 div&#xff0c;并使用 fixed 定位來實現進度條的效果 2.在 Vite Vue 3 項目中&#xf…

Jsp技術入門指南【六】jsp腳本原理及隱式對象

Jsp技術入門指南【六】jsp腳本原理及隱式對象 前言一、JSP 腳本元素1.1 聲明1.2 表達式1.3 腳本標簽 二、JSP 的隱式對象是什么三、隱式對象詳解outrequestsessionapplicationconfigexception 前言 在之前的博客中&#xff0c;我們已經介紹了JSP的環境搭建、編譯文件查找以及生…

vue3推薦的移動table庫

vxe-table https://gitee.com/js-class/vxe-table#https://gitee.com/link?targethttps%3A%2F%2Fvxetable.cn 文檔api https://vxetable.cn/#/component/table/other/bookkeepingVoucher 引入步驟 安裝 npm install xe-utils vxe-tablenext 在項目main.js引入 import …

HOOPS Exchange 與HOOPS Communicator集成:打造工業3D可視化新標桿!

一、概述 在工業3D開發、BIM建筑、數字孿生和仿真分析等高端應用場景中&#xff0c;數據格式復雜、模型體量龐大、實時交互體驗要求高&#xff0c;一直是困擾開發者的難題。Tech Soft 3D旗下的HOOPS Exchange和HOOPS Communicator&#xff0c;正是解決這類問題的黃金搭檔。二者…

《軟件設計師》復習筆記(14.3)——設計模式

目錄 一、設計模式分類 1. 創建型模式&#xff08;Creational Patterns&#xff09; 2. 結構型模式&#xff08;Structural Patterns&#xff09; 3. 行為型模式&#xff08;Behavioral Patterns&#xff09; 真題示例&#xff1a; 一、設計模式分類 架構模式 高層設計決…

HarmonyOS:使用Refresh組件實現頁面下拉刷新上拉加載更多

一、前言 可以進行頁面下拉操作并顯示刷新動效的容器組件。 說明 該組件從API Version 8開始支持。后續版本如有新增內容&#xff0c;則采用上角標單獨標記該內容的起始版本。該組件從API Version 12開始支持與垂直滾動的Swiper和Web的聯動。當Swiper設置loop屬性為true時&…

55、?屏加載?屏怎么進?優化

答&#xff1a; &#xff08;1&#xff09;使?CDN 減?代碼體積&#xff0c;加快請求速度&#xff1b; (2)SSR通過服務端把所有數據全部渲染完成再返回給客?端&#xff1b; (3) 路由懶加載&#xff0c;當??訪問的時候&#xff0c;再加載相應模塊&#xff1b; (4) 使?外…

什么是Python單例模式

什么是Python單例模式 Python單例模式是一種創建型設計模式,目的是確保一個類僅有一個實例,并提供一個全局訪問點來獲取該實例。以下從作用和示例進行介紹: 作用 控制資源使用:避免對系統資源的重復消耗,像數據庫連接、文件句柄等稀缺資源,只創建一個實例來管理使用,防…