題目描述
原題來自:jsoi 2008
給定乙個正整數數列 a1,a2,a3,⋯,an,每乙個數都在 0∼p–1 之間。可以對這列數進行兩種操作:
程式執行的最開始,整數序列為空。寫乙個程式,讀入操作的序列,並輸出詢問操作的答案。
輸入格式
第一行有兩個正整數 m,p,意義如題目描述;
接下來 m 行,每一行表示乙個操作。如果該行的內容是q l
,則表示這個操作是詢問序列中最後 l 個數的最大數是多少;如果是a t
,則表示向序列後面加乙個數,加入的數是 (t+a)modp。其中,t 是輸入的引數,a 是在這個新增操作之前最後乙個詢問操作的答案(如果之前沒有詢問操作,則 a=0)。
第乙個操作一定是新增操作。對於詢問操作,l>0 且不超過當前序列的長度。
輸出格式
對於每乙個詢問操作,輸出一行。該行只有乙個數,即序列中最後 l 個數的最大數。
樣例樣例輸入
10 100
a 97
q 1q 1
a 17
q 2a 63
q 1q 1
q 3a 99
樣例輸出
97
9797
6060
97
樣例說明
最後的序列是 97,14,60,96。
資料範圍與提示
對於全部資料,1≤m≤2×105,1≤p≤2×109,0≤t
sol:首先很容易發現這是一道線段樹模板題,先建一棵20000個節點的線段樹初始全賦為-inf,然後每次修改單個節點,區間查詢就可以了
但是否還有別的做法呢?我看了題解後原來還有逆向st表,很厲害啊
1 #include 2線段樹using
namespace
std;
3const
int n=200005,inf=0x3f3f3f3f,bj=200000;4
intm,mod;
5int
root[n];
6struct
segmenttree
717 inline void change(int l,int r,int pos,int tag,int
x)18
20int mid=(l+r)>>1;21
if(pos<=mid) change(l,mid,pos,tag,x<<1
);22
else change(mid+1,r,pos,tag,x<<1|1
);23 max[x]=max(max[x<<1],max[x<<1|1
]);24
return;25
}26 inline int que(int l,int r,int ql,int qr,int
x)27
34}t;
35int
main()
3656}57
return0;
58}59/*
60input
6110 100
62a 97
63q 1
64q 1
65a 17
66q 2
67a 63
68q 1
69q 1
70q 3
71a 99
72output
7397
7497
7597
7660
7760
7897
79*/
1 #include 2逆向st表using
namespace
std;
3const
int n=200005;4
int bin[23
],log[n];
5int m,mod,f[n][23];6
intmain()729
}30return0;
31}32/*
33input
3410 100
35a 97
36q 1
37q 1
38a 17
39q 2
40a 63
41q 1
42q 1
43q 3
44a 99
45output
4697
4797
4897
4960
5060
5197
52*/
一本通 最大連續和
寫下單調佇列思路怕自己忘 計算區間和的問題,一般轉換為兩個字首和相減,所以我們先求出字首和sum i 表示前i項的和,那麼就轉化成了求 s r s l 1 列舉右端點,則問題變為 找到乙個左端點,i m j i 1 且 s j 最小 然後執行單調佇列的幾個步驟 判斷隊首與i的距離是否超過m的範圍,若...
佇列(一本通)
這道題重點是關係的轉換和初始化 include include include includeusing namespace std int a 101 記錄接著的的那個節點 int n,m int main int ans void bfs int x,int y int main cout in...
題解 一本通1224 最大子矩陣
花兩分鐘靜心看看,望您有所收穫 1224 最大子矩陣 時間限制 1000 ms 記憶體限制 65536 kb 提交數 3073 通過數 1958 已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是1 11 1 子矩陣。比如,如下 4 4 的矩陣 0 2 7 0...