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)\)