BZOJ 2724 分塊統計

2022-05-24 03:42:09 字數 2160 閱讀 2294

區間眾數

先離散化,學到了lagoon的lower_bound+unique的離散化,比我寫的簡單多了

預處理分成sqrt(n)塊,記錄d[i][j]和p[i][j]分別表示從i塊起始位置到j塊終止位置的眾數出現次數和這個數是誰

開乙個陣列,記錄每個數的位置,使得同類的相鄰,同類數的座標公升序排列。

對於詢問:

對於同一塊內或者相鄰塊內的,直接暴力。

對於不同塊內的,統計出非整塊的區間內的所有出現過的數字,然後對這些數字在二分儲存位置的陣列,統計塊內這個數出現的次數。然後結合d[i][j]和p[i][j]就可以得出答案了

view code

1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7

8#define n 1000000

9#define m 2000

1011

using

namespace

std;

1213

intsz,tot;

14int

lt[n],rt[n],ed[m],st[m],sum[n];

15int

q[n],cs[n],p[m][m],d[m][m];

16int

n,m;

17int

val[n],a[n];

18int

ef[n];

19int

bx,by;

2021 inline void

getblock()

2229

if(ed[tot]!=n)

3035

intcnum,csum;

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

3750

else

if(cs[val[k]]==csum)

5154

}55 d[i][j]=csum;

56 p[i][j]=cnum;57}

58}59}

6061 inline void

read()

6269 sort(a+1,a+1+n);

70int num=unique(a+1,a+1+n)-a-1;71

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

72 val[i]=lower_bound(a+1,a+1+num,val[i])-a;

73for(int i=1;i<=n;i++) cs[val[i]]++;

74for(int i=1;i<=num;i++) sum[i]=sum[i-1]+cs[i];

75for(int i=1;i<=num;i++) lt[i]=sum[i-1]+1,rt[i]=sum[i-1

];76

for(int i=1;i<=n;i++) ef[++rt[val[i]]]=i;

7778

getblock();79}

8081 inline int force(int x,int

y)82

93else

if(cs[val[i]]==csum)

9497}98

return

cnum;99}

100101 inline int getsum(int ll,int rr,int

x)102

105106

107 inline int query(int x,int

y)108

121for(int i=st[by];i<=y;i++)

122126 bx++; by--;

127int res=d[bx][by],ans=p[bx][by];

128for(int i=1;i<=h;i++)

129136

else

if(bnt+cs[q[i]]==res)

137140

}141

return

ans;

142}

143144 inline void

go()

145155

}156

157int

main()

158

再一次被二分乾掉了。。。

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.開頭不...

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

題目鏈結 題目大意 給定一段長度為 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 ...