藍橋杯 演算法訓練 操作格仔(線段樹,點更新)

2021-09-06 15:46:11 字數 2789 閱讀 2462

演算法訓練 操作格仔  

時間限制:1.0s   記憶體限制:256.0mb

問題描述

有n個格仔,從左到右放成一排,編號為1-n。

共有m次操作,有3種操作型別:

1.修改乙個格仔的權值,

2.求連續一段格仔權值和,

3.求連續一段格仔的最大值。

對於每個2、3操作輸出你所求出的結果。

輸入格式

第一行2個整數n,m。

接下來一行n個整數表示n個格仔的初始權值。

接下來m行,每行3個整數p,x,y,p表示操作型別,p=1時表示修改格仔x的權值為y,p=2時表示求區間[x,y]內格仔權值和,p=3時表示求區間[x,y]內格仔最大的權值。

輸出格式

有若干行,行數等於p=2或3的操作總數。

每行1個整數,對應了每個p=2或3操作的結果。

樣例輸入

4 31 2 3 4

2 1 3

1 4 3

3 1 4

樣例輸出 6

3資料規模與約定

對於20%的資料n <= 100,m <= 200。

對於50%的資料n <= 5000,m <= 5000。

對於100%的資料1 <= n <= 100000,m <= 100000,0 <= 格仔權值 <= 10000。

線段樹,點更新

線段樹每乙個節點代表乙個區間,並儲存有這個區間的特定值,例如這個區間最大值,區間和等等……而這道題的特定值有兩個,權值和 和 最大權值。

思路

沒有什麼特殊的地方,按照正常的線段樹的思路來做即可。

* 每個節點儲存權值和val,最大權值mx;

1.更新的時候,遞迴找到底,val和mx一起修改,然後一層層的返回的時候,用push_up(),不斷更新val和mx;

2.查詢權值和的時候,遞迴往下找,直到找到要查詢的區間為止,返回該區間節點的權值和val;

3.查詢最大權值的時候,也是遞迴向下找,找到查詢區間之後,返回節點的最大權值mx。

以上就為基本的步驟了,另外注意push_up()的編寫。

寫這道題的時候,線段樹用的還不是很熟,第一遍寫完之後,測試資料不對,又修改了很多地方才通過。所以做線段樹的題,要注意好細節。總的來說,這道題是一道不錯的線段樹的練手題。

**

1 #include 2 #include 3

using

namespace

std;

4#define maxn 100010

5struct

node;

9 node tree[maxn*3+1

];10

int max(int a,int b) //

返回兩數較大值

1114

void push_up(int

d)15

19void init(int d,int l,int r) //

初始化線段樹

2028

29int mid = (l+r)/2

;30 tree[d].left =l;

31 tree[d].right =r;

32 init(d<<1

,l,mid);

33 init(d<<1|1,mid+1

,r);

34push_up(d);35}

36void update(int d,int l,int r,int x) //

1.修改乙個格仔的權值。[l,r]為要找的區間,在這道題裡l==r。x為要修改的值

3743

if(tree[d].left == tree[d].right)

4647

int mid = (tree[d].left+tree[d].right)/2;48

if(mid>=r)

51else

if(mid//

去右區間

52 update(d<<1|1

,l,r,x);53}

54else

58push_up(d);59}

60int query_sum(int d,int l,int r) //

2.求連續一段格仔權值和

6165

if(tree[d].left==tree[d].right)

6869

int mid = (tree[d].left+tree[d].right)/2;70

if(mid>=r)

73else

if(mid76else79}

80int query_max(int d,int l,int r) //

3.求連續一段格仔的最大值

藍橋杯 演算法訓練 操作格仔 (線段樹)

演算法訓練 操作格仔 時間限制 1.0s 記憶體限制 256.0mb 問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m...

藍橋杯 演算法訓練 操作格仔 線段樹

問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...

藍橋杯 演算法訓練 操作格仔(線段樹)

演算法訓練 操作格仔 時間限制 1.0s 記憶體限制 256.0mb 問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m...