BZOJ2724 蒲公英 題解(分塊 區間眾數)

2022-03-26 10:28:07 字數 2173 閱讀 5851

題目鏈結

題目大意:給定一段長度為$n$的序列和$m$次詢問,每次詢問區間$[l,r]$內的最小的眾數。$n\leq 40000,a_i\leq 10^9$

因為$a_i\leq 10^9$,顯然不能開那麼大的陣列。所以要離散化。對於離散化後的陣列,我們維護兩個值$sum[i][j]$和$p[i][j]$。$sum[i][j]$表示前$i$個塊中$j$出現的次數,這個$o(n \sqrt n)$暴力列舉就好。$p[i][j]$表示塊$i$到$j$的眾數,這個只需開乙個桶維護,然後$o(\sqrt n \sqrt n \sqrt n)$暴力列舉就好。

對於查詢,我們仍然暴力把區間$[l,r]$中邊邊角角的部分暴力求出來,對於整塊我們用之前維護的$sum$和$p$即可。

其實就是乙個大模擬……細節有點小多。不會真的有人連敲**都不會吧

**(有些細節的地方有注釋):

#include

using

namespace

std;

const

int maxn=40005

;int n,m,block,tot,sum[205

][maxn];

intlast,pre[maxn],tmpnum[maxn],bucket[maxn],vis[maxn];

struct

node

a[40005

];struct

node

p[205][205

];inline

intread()

while(isdigit(ch))

return x*f;

}bool cmp1(node a,node b)

int getpos(int x)//

不用維護每個區間的左右端點了,乙個函式搞定

inline

void

build()

else

if (bucket[a[k].se]==tmp.s) tmp.num=min(tmp.num,a[k].se);

}p[i][j]=tmp;}}

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

}inline

void query(int l,int

r) printf(

"%d\n

",last=pre[ans]);

return

; }

int ans=p[posl+1][posr-1].num,maxsum=0,maxnum;//

用預處理的p陣列維護ans

vis[ans]=0;tmpnum[ans]=0

;////////////

暴力把邊邊角角統計出來

////////////

//for (int i=l;i<=min(n,posl*block);i++) tmpnum[a[i].se]=0,vis[a[i].se]=0

;

for (int i=(posr-1)*block+1;i<=r;i++) tmpnum[a[i].se]=0,vis[a[i].se]=0

;

for (int i=l;i<=min(n,posl*block);i++) tmpnum[a[i].se]++;

for (int i=(posr-1)*block+1;i<=r;i++) tmpnum[a[i].se]++;

for (int i=l;i<=min(n,posl*block);i++)

for (int i=(posr-1)*block+1;i<=r;i++)

/////////////////////////////////////////////

// if (maxsum>tmpnum[ans]+p[posl+1][posr-1].s) ans=maxnum;

else

if (maxsum==tmpnum[ans]+p[posl+1][posr-1].s) ans=min(ans,maxnum);

printf(

"%d\n

",last=pre[ans]);

}int

main()

sort(a+1,a+n+1

,cmp2);

build();

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

return0;

}

bzoj 2724 蒲公英(分塊)

傳送門biu 分塊,預處理f i,j 為第i塊到第j塊的眾數。每次查詢區間眾數時,可能作為答案的種類只有完整的塊中的眾數和不完整的塊中的數最多2 n 1 種。二分求一下區間中出現的次數就可以了。include using namespace std int n,m,lastans,p int blo...

bzoj 2724 蒲公英 (分塊 離散化)

題解 這種東西想想也感覺線段樹之類的很難維護,所以就用相對更暴力 功能更強的分塊。因為眾數不具有區間可加性,所以用樹狀陣列或者線段樹維護就十分困難。我們可以採用分塊演算法。把序列a分成t塊,每塊長度l n t 對於每個詢問 l,r 設l處於第p塊,r處於第q塊。把區間 l,r 分成三部分 1.開頭不...

BZOJ 2724 分塊統計

區間眾數 先離散化,學到了lagoon的lower bound unique的離散化,比我寫的簡單多了 預處理分成sqrt n 塊,記錄d i j 和p i j 分別表示從i塊起始位置到j塊終止位置的眾數出現次數和這個數是誰 開乙個陣列,記錄每個數的位置,使得同類的相鄰,同類數的座標公升序排列。對於...