最大數 洛谷1198 JSOI2008

2021-08-14 05:10:19 字數 1296 閱讀 1511

題意:

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

1、 查詢操作。

語法:q l

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

限制:l不超過當前數列的長度。(l>=0)

2、 插入操作。

語法:a n

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

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

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

本題可以用線段樹做(在洛谷上能過,但是我的**在bzoj會t),似乎還可以單調佇列甚至分塊。我目前寫的線段樹都是傳統的寫法,不是zkw線段樹。查詢就是區間求區間[n-l+1,n]的最大值。記錄一下上乙個插入操作的返回值,然後插入相當於單點修改。那麼考慮一下建樹,發現在一開始我們不知道每個點的權值,所以我們只需要建一棵空樹,建空樹的目的是確定每個節點的左右子節點的編號。本題有乙個小細節:當一開始數列裡沒有數的時候也會詢問你最大數值,這時候要特判一下,輸出0

下面發一下在洛谷ac的**:(此**直接交到bzoj會re,原因尚不清楚)

#include using namespace std;

int m,d;

char s;

int ji,cnt;

struct node

tr[4000050];

void build(int rt,int l,int r)

int mid=(l+r)>>1;

build(rt<<1,l,mid);

build(rt<<1|1,mid+1,r);

return;

}void pushdown(int rt)

return;

}void update(int rt,int le,int ri,long long x)

pushdown(rt);

int mid=(l+r)>>1;

if(le<=mid)

update(rt<<1,le,ri,x);

if(ri>mid)

update(rt<<1|1,le,ri,x);

tr[rt].maxn=max(tr[rt<<1].maxn,tr[rt<<1|1].maxn);

return;

}int query(int rt,int le,int ri)

int main()

if(s=='a')

}return 0;

}

洛谷1198 JSOI2008 最大數

題目 最大數 思路 線段樹。最開始就建乙個m個點的線段樹,這樣對數列增加的操作就變成線段樹的單點修改了。注意 在l 0時,要輸出0,所以不可以把線段樹的值初始化成 inf。另外注意邊界,不然會mle。建議在bzoj過了的也在luogu交一下,這題bzoj的資料比較水一點。includeusing n...

洛谷1198 最大數

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

洛谷 P1198 JSOI2008 最大數

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