洛谷 P1198 最大數

2021-07-22 09:59:58 字數 1486 閱讀 5317

題目描述

現在請求你維護乙個數列,要求提供以下兩種操作:

1、 查詢操作。

語法:q l

功能:查詢當前數列中末尾l個數中的最大的數,並輸出這個數的值。

限制:l不超過當前數列的長度。

2、 插入操作。

語法:a n

功能:將n加上t,其中t是最近一次查詢操作的答案(如果還未執行過查詢操作,則t=0),並將所得結果對乙個固定的常數d取模,將所得答案插入到數列的末尾。

限制:n是整數(可能為負數)並且在長整範圍內。

注意:初始時數列是空的,沒有乙個數。

輸入輸出格式

輸入格式:

第一行兩個整數,m和d,其中m表示操作的個數(m <= 200,000),d如上文中所述,滿足(0 < d < 2,000,000,000)

接下來的m行,每行乙個字串,描述乙個具體的操作。語法如上文所述。

輸出格式:

對於每乙個查詢操作,你應該按照順序依次輸出結果,每個結果佔一行。

輸入輸出樣例

輸入樣例#1:

5 100

a 96

q 1

a 97

q 1

q 2輸出樣例#1:

96 93

96說明

[jsoi2008]

【分析】

用線段樹做的話很裸…思路比較簡單即可出解。

但由於題目要求求最後l個數中的最大數,那麼我們可以維護乙個單調棧。

假如兩x,y x先進棧,y後進棧,那麼如果x可以選擇的話,y也一定可以選擇。

那麼如果y>x的話 ,x就沒用了,就可以彈出了

於是剩下的就是乙個單調遞減的單調棧

因為查詢是查詢後l個數,於是我們要找乙個棧中盡量靠左的數,使得它在最後l個進棧的數中,我們僅靠數字並不知道它是否符合要求,

所以這要求我們每個數給乙個進棧時間點id,再設乙個一共進了多少個數(不是棧中數的個數)變數id_cnt,每次進棧操作時++,這樣的話,能選擇的數的id>=id_cnt-l+1

(這樣搞主要是因為有退棧現象發生)

然後對於每次q操作 在棧中二分查詢

【**】

//洛谷 p1198 最大數

#include

#include

#include

#define m(a) memset(a,0,sizeof a)

#define fo(i,j,k) for(i=j;i<=k;i++)

using

namespace

std;

int k,top,q,d,t,n;

int a[200001],s[200001];

char c[3];

inline

int query(int x)

return a[s[l]];

}int main()

else

}return

0;}

洛谷 P1198 最大數

首先這是一道線段樹裸題,但是線段樹長度不確定,那麼我們可以在建樹的時候,將每乙個節點初始化為 inf,每次往隊尾加乙個元素即一次單節點更新,注意本題的資料範圍,其實並不用開 long long,具體請看注釋。include include include include define lson l,...

洛谷 P1198 最大數 線段樹

要問區間最大值,肯定是要用線段樹的,不能用樹狀陣列。因為沒有逆元?但是題目求的是最後一段,可以改成類似字首和啊。不行!插入新元素之後更新的複雜度太高了!所以我們就弄乙個初始元素是負數的最大值線段樹,每次插入就是把末尾的元素 update 查詢就是查詢末尾的區間最大值,這樣每次修改 查詢的複雜度是 o...

洛谷1198 最大數

寫了那麼多xx樹和單調佇列後,不如試試爽翻天的倍 r 增 m 吧 q 對於每乙個點,維護從它為起點向左2 j長度的最大值。查詢的時候從大往小列舉2 j更新最大值就行。等等好像 注釋裡面寫過這些了 不保證 的正確性。反正洛谷的資料水過了。1 include 2 include 3 include 4 ...