回滾莫隊
題目描述
ioi國歷史研究的第一人——joi教授,最近獲得了乙份被認為是古代ioi國的住民寫下的日記。joi教授為了通過這份日記來研究古代ioi國的生活,開始著手調查日記中記載的事件。
日記中記錄了連續n天發生的時間,大約每天發生一件。
事件有種類之分。第i天(1<=i<=n)發生的事件的種類用乙個整數xi表示,xi越大,事件的規模就越大。
joi教授決定用如下的方法分析這些日記:
1.選擇日記中連續的一些天作為分析的時間段
2.事件種類t的重要度為t×(這段時間內重要度為t的事件數)
3.計算出所有事件種類的重要度,輸出其中的最大值
現在你被要求製作乙個幫助教授分析的程式,每次給出分析的區間,你需要輸出重要度的最大值。
輸入格式
第一行兩個空格分隔的整數n和q,表示日記一共記錄了n天,詢問有q次。
接下來一行n個空格分隔的整數x1…xn,xi表示第i天發生的事件的種類
接下來q行,第i行(1<=i<=q)有兩個空格分隔整數ai和bi,表示第i次詢問的區間為[ai,bi]。
普通莫隊適用於區間的增大和縮小都好處理的情況,但有的情況刪除並不好處理,回滾莫隊很好地解決了這個問題。
其關鍵在於,分塊處理,左右端點在乙個塊中則暴力處理,否則由於莫隊的排序在左節點在同一塊時,有節點是遞增的,我們只要遞增處理右節點,則右側沒有刪除;然後左節點沒處理乙個問題就回溯到當前塊尾,則左側也沒有刪除操作,左右都是o(n
n)
o(n\sqrt n)
o(nn)
#include
#include
#include
#include
using
namespace std;
typedef long
long ll;
const ll maxn=
1e5+10;
ll ans[maxn]
;ll a[maxn]
;ll b[maxn]
;ll pos[maxn]
;ll be[maxn]
;ll low[maxn]
;ll high[maxn]
;ll cnt[maxn]
;//用於莫隊
ll cnt2[maxn]
;//用於左右段點在同一塊時的暴力
struct q
}q[maxn]
;int
main()
} high[bnum]
=n;for
(ll i=
1;i<=n;i++
)sort
(b+1
,b+1
+n);
ll tot=
unique
(b+1
,b+1
+n)-b-1;
for(ll i=
1;i<=n;i++
)for
(ll i=
1;i<=m;i++
)sort
(q+1
,q+1
+m);
ll j=1;
for(ll i=
1;i<=bnum;i++
)for
(ll k=ql;k<=qr;k++
) ans[q[j]
.id]
=tmp;
}else
tmp=now;
while
(l>ql)
ans[q[j]
.id]
=now;
while
(l) now=tmp;}}
}for
(ll i=
1;i<=m;i++
)}
Luogu AT1219 歴史 研究
長度為n的序列a,定義區間內乙個數的價值為 數值 出現次數,問區間內的數的最大價值是多少。m個詢問,每個詢問給出 l,r l,r l,r 問區間內數的最大價值。1 n m 1 05,1 a i 1 091 n,m 10 5,1 a i 10 9 1 n m 1 05,1 a i 1 09引入乙個大佬...
題解 AT1219 歴史 研究
簡單分析 題面含有ioi 驚 可知此題是ioi 數字三角形 難度 逃 當然很多人都是抱著學回滾莫隊的目標來看這道題的,所以這裡介紹一下回滾莫隊。1 按莫隊的思路講詢問排序。2 查詢時列舉每個區間,我們需要保證右端點是保持單調遞增的,同時左端點每次在乙個塊中移動,以此來計算每個詢問的值。3 每一次到下...
AT1219 歴史 研究 回滾莫隊
題目描述見鏈結 直接使用莫隊,但是這道題目刪除時不好尋找次大值,考慮回滾莫隊,回滾莫隊的處理方式與莫隊大致是相同的,具體來說 對兩個相鄰的詢問區間 l r l,r l r l,r l r l r 若 b k id l bk id r bk id l bk id r bk id l b k id r ...