ACM I Hate It(線段樹的進化版)

2022-04-05 14:33:12 字數 2439 閱讀 1239

description

很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。

這讓很多學生很反感。

不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫乙個程式,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績。

input

本題目包含多組測試,請處理到檔案結束。

在每個測試的第一行,有兩個正整數 n 和 m ( 0,分別代表學生的數目和操作的數目。

學生id編號分別從1編到n。

第二行包含n個整數,代表這n個學生的初始成績,其中第i個數代表id為i的學生的成績。

接下來有m行。每一行有乙個字元 c (只取'q'或'u') ,和兩個正整數a,b。

當c為'q'的時候,表示這是一條詢問操作,它詢問id從a到b(包括a,b)的學生當中,成績最高的是多少。

當c為'u'的時候,表示這是一條更新操作,要求把id為a的學生的成績更改為b。

output

對於每一次詢問操作,在一行裡面輸出最高成績。

sample input

5 6
1 2 3 4 5

q 1 5

u 3 6

q 3 4

q 4 5

u 2 9

q 1 5

sample output

565

9

hint

huge input,the c function scanf() will work better than cin

解釋:這題主要意思難點在如何花較少時間去取得一段學生的最高成績如何更新某個學生的成績。所以此題,有以下思路:

1.在構建每個線段樹的時候,除了最下面的一排,每乙個支點都儲存下面左孩子和右孩子的最大值(不是和),這樣的話讀取某段學生

成績最大值就會快很多。

2.因為每次跟新某位學生成績時,上面的支點肯定也要做相應改變,所以用到了遞迴思想從下到上更新

成績。下面是**:

1 #include2 #include3 #include4

#define max(a,b) (a > b ? a : b)

5#define min(a,b) (a > b ? b : a)67

using

namespace

std;89

const

int maxn=200010;10

11struct

student

12segtree[maxn*3

];16

intnum[maxn];

1718

1920

21void build(int i,int left,int right)//

遞迴演算法,構建一顆線段樹

2230

int mid=(left+right)>>1;//

除231 build(i<<1,left,mid);//

i*2 a

32 build(i<<1|1,mid+1,right);//

i*2+1 b

33 segtree[i].nsum=(segtree[i<<1].nsum>segtree[i<<1|1].nsum?segtree[i<<1].nsum:segtree[i<<1|1].nsum); //

取最大值34}

3536

37void u(int i,int tleft,int b)//

更新成績

3845

int mid=(segtree[i].left+segtree[i].right)>>1;46

47if(tleft<=mid)

48 u(i<<1

,tleft,b);

49else

50 u(i<<1|1

,tleft,b);

5152 segtree[i].nsum=(segtree[i].nsum>b?segtree[i].nsum:b);

5354}55

5657

int q(int i,int left,int

right)

5863

int middle=(segtree[i].left+segtree[i].right)>>1;64

if(left>middle)

6568

else

if(right<=middle)

6972

else

7378}79

8081

intmain()

82

97}

98return0;

99 }

牛客 紅球進黑洞 (線段樹 位運算)

銘宇巨巨推薦的題!原題鏈結 題意 給定乙個序列,兩種操作,一是區間求和,二是將區間裡的每個數都異或x。思路 一眼就線段樹,關鍵是怎麼維護第二個操作。借助最小異或生成樹的思想以及異或題的常見套路,我們可以把每個數都進行二進位制拆分,用線段樹分別維護每一位上的0和1。對於操作二,我們只需要分別維護每一位...

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...