題目鏈結
題意:給定乙個正整數數列 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取模,將所得答案插入到數列的末尾。重新賦值 從題解上看到一種單調棧的寫法覺得非常巧妙 利用了題目的特性 每次都是在最後詢問,用單調棧維護,開兩個棧乙個儲存下...