線段樹 最大數

2021-10-02 13:49:56 字數 2129 閱讀 7833

給定乙個正整數數列 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×1

05

1≤m≤2×10^5

1≤m≤2×

105,

1 ≤p

≤2×1

09

1≤p≤2×10^9

1≤p≤2×

109,

0 ≤t

<

p0≤t0≤

t<

p輸入樣例:

10 100

a 97

q 1q 1

a 17

q 2a 63

q 1q 1

q 3a 99

輸出樣例:

9797

9760

6097

樣例解釋

最後的序列是 97,14,60,96。

因為這些數的排列會按照操作順序來確定。所以我們先把這些操作的位置的坑先建立,然後每放乙個數便讓我們當前區間+1,然後就是線段樹的單點修改和區間最值查詢了。

#include

//#define int long long

#define lson rt<<1

#define rson rt<<1|1

using

namespace std;

const

int n=

2e5+7;

int m,p,cnt;

struct node

tr[n<<2]

;void

pushup

(int rt)

void

build

(int rt,

int l,

int r);if

(l==r)

return

;int mid=l+r>>1;

build

(lson,l,mid)

;build

(rson,mid+

1,r)

;pushup

(rt);}

intquery

(int rt,

int l,

int r)

int mid=tr[rt]

.l+tr[rt]

.r>>1;

int v=0;

if(l<=mid) v =

query

(lson,l,r);if

(r>mid) v =

max(v,

query

(rson, l, r));

return v;

}void

modify

(int rt,

int x,

int c)

int mid=tr[rt]

.l+tr[rt]

.r>>1;

if(x<=mid)

modify

(lson,x,c)

;else

modify

(rson,x,c)

;pushup

(rt);}

intmain()

else

}return0;

}

最大數(線段樹 單調棧)

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

洛谷1198最大數(線段樹)

現在請求你維護乙個數列,要求提供以下兩種操作 1 查詢操作。語法 q l 功能 查詢當前數列中末尾l個數中的最大的數,並輸出這個數的值。限制 l不超過當前數列的長度。2 插入操作。語法 a n 功能 將n加上t,其中t是最近一次查詢操作的答案 如果還未執行過查詢操作,則t 0 並將所得結果對乙個固定...

洛谷1198 最大數 線段樹

現在請求你維護乙個數列,要求提供以下兩種操作 1 查詢操作。語法 q l 功能 查詢當前數列中末尾l個數中的最大的數,並輸出這個數的值。限制 l不超過當前數列的長度。l 0 2 插入操作。語法 a n 功能 將n加上t,其中t是最近一次查詢操作的答案 如果還未執行過查詢操作,則t 0 並將所得結果對...