演算法訓練 操作格仔

2021-07-28 07:22:42 字數 1657 閱讀 7783

問題描述

有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 3

1 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。

解答**

#include#includeusing namespace std;

int max(int a,int b)

typedef struct node

node;

node a[400010];//申請線段樹節點空間

void build(int n,int l,int r);

void insert(int n, int v, int num);//為線段樹插入乙個值

void change(int n, int v, int num);//為線段樹改變乙個權值

int qsum(int n, int l, int r);//求乙個範圍內的權值總和

int qmax(int n, int l, int r);//求乙個範圍內的最大值

int main()

while(m--)

}return 0;

}void build(int n,int l,int r)//構建一棵範圍在l至r範圍的線段樹

void insert(int n, int v, int num)//為線段樹插入乙個值

void change(int n, int v, int num)//為線段樹改變乙個權值

int middle = (a[n].l + a[n].r) / 2;

if(v <= middle)

change(n*2, v, num);//更改左孩子

else

change(n*2+1, v, num);//更改右孩子

a[n].sum = a[n*2].sum + a[n*2+1].sum;//更新總和

a[n].max = max(a[n*2].max,a[n*2+1].max);//更新最大值

}int qsum(int n, int l, int r)//求乙個範圍內的權值總和

int qmax(int n, int l, int r)//計算b至c範圍內的最大權值

演算法訓練 操作格仔

演算法訓練 操作格仔 時間限制 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...

演算法訓練 操作格仔

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