AT1219 歷史研究

2021-09-10 13:55:03 字數 2429 閱讀 5468

\(ioi\)國歷史研究的第一人——\(joi\)教授,最近獲得了乙份被認為是古代\(ioi\)國的住民寫下的日記。\(joi\)教授為了通過這份日記來研究古代\(ioi\)國的生活,開始著手調查日記中記載的事件。

日記中記錄了連續\(n\)天發生的時間,大約每天發生一件。

事件有種類之分。第\(i\)天\((1<=i<=n)\)發生的事件的種類用乙個整數\(x_i\)表示,\(x_i\)越大,事件的規模就越大。

\(joi\)教授決定用如下的方法分析這些日記:

選擇日記中連續的一些天作為分析的時間段

事件種類t的重要度為t*(這段時間內重要度為t的事件數)

計算出所有事件種類的重要度,輸出其中的最大值 現在你被要求製作乙個幫助教授分析的程式,每次給出分析的區間,你需要輸出重要度的最大值。

第一行兩個空格分隔的整數\(n\)和\(q\),表示日記一共記錄了\(n\)天,詢問有\(q\)次。

接下來一行\(n\)個空格分隔的整數\(x_1…x_n\),\(x_i\)表示第\(i\)天發生的事件的種類

接下來\(q\)行,第\(i\)行\((1<=i<=q)\)有兩個空格分隔整數\(a_i\)和\(b_i\),表示第\(i\)次詢問的區間為\([a_i,b_i]\)。

輸出\(q\)行,第\(i\)行\((1<=i<=q)\)乙個整數,表示第i次詢問的最大重要度

輸入:

5 5

9 8 7 8 9

1 23 4

4 41 4

2 4

輸出:

988

1616

\(1<=n<=105\)

\(1<=q<=105\)

\(1<=x_i<=109 (1<=i<=n)\)

莫隊,回滾莫隊,離線詢問,排序算嗎

我們發現對於暴力的資料,我們之所以要套個線段樹是因為莫隊中的 \(del​\) 操作執行後無法繼續保證最大值的維護。那麼我們換個思路想一下,我們避免掉 \(del​\) 操作的執行不就好了嗎?

這就是回滾莫隊的板子了。

對於 \(r-l>=塊大小\) 的詢問,直接暴力處理。

對於左端點在同乙個塊內的詢問,我們在處理之前先令 \(l\) 處在下乙個塊的塊首,然後不斷 \(r++\) 到詢問右端點,那麼 \(r\) 就保證不會執行 \(del\) 操作了。而對於 \(l\) ,當前 \(r\) 處理完之後,記錄下當前的狀態(包括最大值和每個種類的**數量啥的),我們只需要對於每個詢問移動到詢問左端點,然後得到答案之後 \(o(1)\) 跳回之前狀態即可。

那麼對於記錄狀態與跳回怎麼處理呢?表面上看上去記錄每個種類**數量的狀態是 \(o(n)\) 的,但是並不是。顯然,我們先對於 \(r\) 端跳躍的時候使用陣列 \(a\) 記錄下每種**的數量,\(l\) 端跳躍的時候用陣列 \(b\) 記錄下每種**的數量。

然後,我們使用 \(t\) 陣列記錄 \(b\) 中每個元素上次修改是在第幾次操作的時候,如果上次修改不是當前操作,那麼我們將 \(t\) 陣列更新為當前操作值,同時將 \(b\) 陣列中當前元素變更為 \(a\) 陣列對應下標的元素。這樣我們只要在移動 \(l\) 的時候對 \(b\) 陣列進行判斷更新即可。

然後輸出答案就好了。

#include#include#include#include#includeusing namespace std;

int n,q,a[100001],cnt,key[100001],book[2][100001],size,t[100001],now,c;

int l,r,lnow;

long long ans,ans[100001],maxx,nowmax;

void max(long long &a,long long b)

struct que

k[100001];

struct number

num[100001];

bool cmp(number a,number b)

sort(num+1,num+n+1,cmp);

for(int i=1;i<=n;i++)

for(int i=1;i<=q;i++)

}sort(k+1,k+q+1,cmp2);

k[0].q=-1;

for(int i=1;i<=q-c;i++)

l=lnow;

while(rk[i].l)add(--l);

ans[k[i].d]=nowmax;

}for(int i=1;i<=q;i++)

printf("%lld\n",ans[i]);

}

posted @

2019-01-29 14:40

洛水·錦依衛 閱讀(

...)

編輯收藏

Atcoder 1219 歷史研究

題目 回滾莫隊,大概是一種莫隊的小trick 對序列分塊,對於左右端點在同乙個塊裡的直接暴力 其餘的詢問按照左端點所在塊分類,乙個塊內按照右端點公升序排序 我們維護乙個指標 rp 記錄當前右端點的位置,對於乙個詢問 l,r 設其所在塊的右端點為 r 我們將 rp 暴力移動到 r 的位置 由於右端點單...

題解 AT1219 歴史 研究

簡單分析 題面含有ioi 驚 可知此題是ioi 數字三角形 難度 逃 當然很多人都是抱著學回滾莫隊的目標來看這道題的,所以這裡介紹一下回滾莫隊。1 按莫隊的思路講詢問排序。2 查詢時列舉每個區間,我們需要保證右端點是保持單調遞增的,同時左端點每次在乙個塊中移動,以此來計算每個詢問的值。3 每一次到下...

4241 歷史研究

這一題我還是不會做qaq 一開始想了一想,好像可以上莫隊 嗯,怎麼維護修改呢 我們可以對數值進行分塊啊,那麼每次就只需要n 的時間就可以維護好了 v 嗯,看起來是乙個十分優越的做法 時間複雜度就是莫隊 n 也就是n nn 大概是n2 這就跟暴力沒什麼區別嘛,就名字好聽了一點 於是繼續想。什麼都沒想出...