給定乙個正整數數列 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 並將所得結果對...