AT1219 JOI2013 歴史 研究

2021-10-07 22:39:24 字數 1911 閱讀 2379

回滾莫隊

題目描述

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 ...