線段樹 最大數 單點修改 求區間最大值

2021-10-02 15:23:41 字數 1530 閱讀 5470

題目鏈結

題意:給定乙個正整數數列 a1,a2,…,an,每乙個數都在 0∼p−1 之間。

可以對這列數進行兩種操作:

新增操作:向序列後新增乙個數,序列長度變成 n+1;

詢問操作:詢問這個序列中最後 l 個數中最大的數是多少。

程式執行的最開始,整數序列為空。

寫乙個程式,讀入操作的序列,並輸出詢問操作的答案。

輸入格式

第一行有兩個正整數 m,p,意義如題目描述;

接下來 m 行,每一行表示乙個操作。

如果該行的內容是 q l,則表示這個操作是詢問序列中最後 l 個數的最大數是多少;

如果是 a t,則表示向序列後面加乙個數,加入的數是 (t+a) mod p。其中,t 是輸入的引數,a 是在這個新增操作之前最後乙個詢問操作的答案(如果之前沒有詢問操作,則 a=0)。

第乙個操作一定是新增操作。對於詢問操作,l>0 且不超過當前序列的長度。

輸出格式

對於每乙個詢問操作,輸出一行。該行只有乙個數,即序列中最後 l 個數的最大數。

資料範圍

1≤m≤2×105,

1≤p≤2×109,

0≤t#include

#include

#include

#include

using

namespace std;

const

int n =

2e5+5;

int m, p;

struct node

tr[n <<2]

;//線段樹一般要開四倍的空間避免越界

//建立或修改父節點,父節點的max就是兩個子節點max的最值

void

pushup

(node &u, node &l, node &r)

void

pushup

(int u)

//建樹

void

build

(int u,

int l,

int r)

;//如果已經是葉節點

if(l == r)

return

;int mid = l + r >>1;

//遞迴建立左右兒子區間

build

(u <<

1, l, mid)

;build

(u <<1|

1, mid +

1, r);}

//u表示當前查詢的端點,l,r表示查詢的區間

intquery

(int u,

int l,

int r)

//更新節點

void

modify

(int u,

int x,

int v)

}int

main()

else

}return0;

}

線段樹求區間最大值(單點修改)

問最大值 q a b 詢問 a,b 中最大值 c a b 將a點值改為b includeusing namespace std pragma warning disable 4996 define maxn 100005 define ll long long ll chushi maxn sum ...

線段樹 最大數

給定乙個正整數數列 a1,a2,an,每乙個數都在 0 p 1 之間。可以對這列數進行兩種操作 新增操作 向序列後新增乙個數,序列長度變成 n 1 詢問操作 詢問這個序列中最後 l 個數中最大的數是多少。程式執行的最開始,整數序列為空。寫乙個程式,讀入操作的序列,並輸出詢問操作的答案。輸入格式 第一...

最大數(線段樹 單調棧)

寫線段樹的話太裸了,但是題意非常難搞,認真讀題 其中t是最近一次查詢操作的答案 如果還未執行過查詢操作,則t 0 並將所得結果對乙個固定的常數d取模,將所得答案插入到數列的末尾。重新賦值 從題解上看到一種單調棧的寫法覺得非常巧妙 利用了題目的特性 每次都是在最後詢問,用單調棧維護,開兩個棧乙個儲存下...