lxl分塊糊做

LuoyuSitfitw發表於2024-06-23

lxl分塊糊做

[Ynoi2017] 由乃打撲克

me

想到了二分這個值+分塊去找\(\leq\)這個數的數的數量,複雜度\(O(Q\log^2 N\sqrt N)\),然後塊內可能用\(multiset\)或者啥來維護

tj

更優的做法是塊內維護一個排好序的序列,不過硬要說和\(multiset\)本質確實一樣,但是這樣常數和寫法上會優的多

CodeChef Chef and Churu

me

對函式的下標分塊,然後對每個塊內維護兩個序列,一個以\(l\)從小到大排序,一個以\(r\)從大到小排序

然後修改時,可以把所有函式都\(+y-a_x\),然後再把那些\(r<x\)\(l>x\)的函式的值\(+a_x-y\),有個很好的點就是這兩個條件只會至多滿足一個,這個就可以對於每個塊算出塊的答案,然後給兩個序列的最後一個滿足條件的掛上一個\(tag\)

查詢的時候整塊直接用存的那個值即可,散塊就可以遍歷塊對應的兩個序列,然後算\(tag\)的貢獻

\(O(Q\sqrt N\log N)\)

tj

對下標分塊,然後陣列和函式都分塊

函式查詢\([l,r]\)可以變成查詢\([l,n]-[r+1,n]\),於是可以給\([l,n]\)的數的\(tag+1\)\([r+1,n]\)\(tag-1\),這個\(tag\)表示一個數的值被計算的次數

然後函式的塊要維護整塊的答案,查詢到整塊就用函式的塊

查詢到散塊的時候,可以用陣列的塊來\(O(1)\)的查詢

複雜度\(O(Q\sqrt N)\)

Luogu3863 序列

me

不會喵

tj

以下標為一個軸,時間為另一個軸,然後值為此時間下此下標上的值

可以發現修改是修改的一個矩形,查詢的是一個區間

於是可以掃描線+分塊維護

\(O(Q\sqrt N\log N)\)

「BZOJ2038」小 Z 的襪子

me

一開始一直在想分塊,然後感覺分塊不可做,突然想到為啥不離線呢,於是就是莫隊板子

\(O(Q\sqrt N)\)

[AHOI2013]作業

me

莫隊,然後再用個樹狀陣列來記錄答案

\(O(Q\sqrt N\log N)\)

tj

對值域也分塊,就可以去掉\(log\)

[Ynoi2016]這是我自己的發明

me

首先可以用\(dfn\)序把子樹變成區間,然後一開始欽定\(1\)是根,如果後面根變成\(x\)的孩子\(y\)的子樹中的一個點,對於\(x\),它的新子樹區間就是整個區間除去\(y\)子樹的區間

那麼現在就相當於查詢兩個區間\([a,b]\)\([l,r]\)\(\sum c_{[a,b]}(i)\times c_{[l,r]}(i)\),於是可以類似於Luogu3863 序列,以一個查詢為\(x\)軸,另一個為\(y\)軸,得到一個\(n\times n\)的矩陣,然後\(a_{i,j}=[col_i==col_j]\),查詢即詢問左下角為\((a,l)\),右上角\((b,r)\)的矩形的權值和

然後矩形的權值和可以用二維字首和拆分成四個左下角\((1,1)\),右上角為\((x,y)\)的查詢,那麼原問題就被拆分成了許多個這樣的查詢,這個可以莫隊維護

\(O(Q\sqrt N)\)

bzoj3920 Yuuna的禮物

me

區間查詢可以莫隊維護,然後\(k1\)可以數狀陣列/分塊維護,\(k2\)可以\(set\)維護。。。?寫的時候突然發現不行,幽默

tj

很牛!考慮用點來表示權值為\(v\)的點出現了\(k\)次,那麼共有\(n\)個點,將這些點按照出現次數為第一關鍵字,權值為第二關鍵字排序,然後對這些點進行分塊即可

\(O(Q\sqrt N)\)

[JOI2014] 歷史研究(歴史の研究)

me

回滾莫隊,\(O((N+Q)\sqrt N)\)

tj

回滾莫隊是其中一個做法,還有普通莫隊的做法

和bzoj3920 Yuuna的禮物類似,用點來表示權值為\(v\)的點出現了\(k\)次,那麼共有\(n\)個點,將這些點按照\(v\times k\)排序,對這些點分塊,那麼用莫隊維護區間,此時答案就是這\(n\)個點中,最靠後的存在的點

HNOI2016大數

me

就求區間內字首餘數相同的對數即可,莫隊,\(O(Q\sqrt N)\)

tj

\(p=2/5\)的情況比較特殊,因為它們和\(10\)不互質

[IOI2009]regions

me

這怎麼分塊,都不讓離線

tj

原來是根號分治,你說這個我就懂了嘛,幽默,根號分治算分塊嗎\(/fn\)

考慮當\(r_1\)\(r_2\)中的某一個大小大於\(B\)時,因為最多隻存在\(\frac nB\)個這樣的地區,所以考慮預處理

預處理\(r_1\)時,若為地區\(V\),可以直接\(dfs\),然後\(cnt\)記錄\(x\)的祖先中有幾個屬於地區\(V\)的,然後記錄進\((V,a_x)\)

預處理\(r_2\)時,若為地區\(V\),依舊\(dfs\),記\(cnt\)\(x\)的子樹中有幾個屬於地區\(V\)的,然後記錄進\((a_x,V)\)

這部分複雜度\(O(\frac{n^2}B)\)

然後若兩個都大小小於\(B\),則考慮\(dfn\)序,若\(y\)\(x\)的孩子當且僅當\(dfn_y\in[dfn_x,dfn_x+sz_x-1]\),那麼考慮對地區\(r_1\)維護兩個序列,一個以\(dfn_x\)排序,一個以\(dfn_x+sz_x-1\)排序,\(r_2\)維護一個以\(dfn_y\)排序的序列,那麼對於\(r_1\)中的點\(x\),在\(r_2\)中合法的\(y\)的範圍為第\(l\)個到第\(r\)個,那麼\(x\)的貢獻為\(r-l+1\),拆開成\(r+1\)\(-l\)\(r+1\)\(r_1\)的第二個序列負責,\(-l\)由第一個序列負責,然後雙指標即可

複雜度\(O(QB)\)

因為\(N\)\(Q\)同階,所以\(B=\sqrt N\),總複雜度\(O(N\sqrt N)\)

SHOI2006 Homework

me

感覺對\(Y\)分塊,然後透過什麼性質每次\(X\)去更新\(Y\)的答案沒啥出路,考慮每次對\(Y\)去找\(X\)

首先\(Y\leq B\)的,只有\(B\)個,這個可以每次用\(X\)去更新\(Y\)的答案

對於\(Y>B\)的,設\(X=k\times Y+r\),則只有\(\frac VB\)\(k\),那麼考慮對\(Y\)去找\(X\),列舉\(k\),找到\(\geq k\times Y\)的最小的\(X'\),然後答案取\(min(ans,X'-k\times Y)\),可以用分塊做到\(O(1)\)查詢,\(O(\sqrt V)\)維護

\(B\)\(\sqrt V\),複雜度\(O(N\sqrt V)\)

[Ynoi2015] 此時此刻的光輝

me

對於\(c\leq B\)的,只有\(B\)個,預處理

對於\(c>B\)的,最多走\(\frac nB\)步,直接跳

\(O(N\sqrt N\log N)\)

tj

可以長鏈剖分做到\(O(1)\)\(k\)級祖先,於是\(O(N\log N+N\sqrt N)\)

具體的大概就是對於每條長鏈,記錄鏈頂向上的第\(k\)個點與鏈上第\(k\)個點,\(k\leq\)這條長鏈的長度

題解 P5903 【【模板】樹上 k 級祖先

「Ynoi2015」 盼君勿忘

me

莫隊維護區間,\(ans=\sum c_i\times(2^{len}-2^{cnt_i})\)

\(cnt_i\leq B\)的放到一起,然後算答案的時候列舉\(cnt_i\)算即可

\(cnt_i>B\)的最多\(\frac nB\)個,這個單獨算即可

\(O(Q\sqrt N\log N)\)

tj

最佳化了快速冪,用了光速冪,具體就是預處理出\(pw_i\)\(i\in[1,B]\),以及\(pw_{i\times B}\)

\(O(Q\sqrt N)\)

相關文章