分塊可以解決幾乎全部的區間查詢區間更新等問題,功能比線段樹和樹狀陣列要強大,但是時間複雜度會更大一點。其實分塊就是一種優化過的暴力,它是對於整體進行像線段樹一樣的維護,對區域性進行暴力的修改。
顧名思義分塊分塊,我們把長度為n的序列分為若干塊。維護塊內資訊即可。
又要問了,要多大呢?通常將塊的大小設為n
\sqrt n
n,用pos陣列儲存每個塊的位置。
最後分完有剩,那麼剩餘的單獨為乙個塊。
我們用線段樹的例題來介紹傳送門luogup3372
題目要求:
1.區間更新:
我們找在這個區間有多少個塊是全部在裡面的,因為這些塊全要更新,我們可以新增懶惰標記,下次要用時才更新。
對於部分在區間的塊,我們只有暴力的把這些在區間內的點更新即可、
2.區間查詢:
還是討論如果被區間包含的塊,就直接加上處理懶標的值和之前的和即可。
部分在區間的塊,就暴力計算值即可。
**非常簡單。也好理解。
#include
using
namespace
std;
#define int long long
const
int n=
1e5+5;
int n,m,a[n]
;int pos[n]
,sum[n]
,l[n]
,r[n]
,lz[n]
;//塊的位置,塊的和,塊的左區間和右區間,懶惰標記
inline void
build()
r[num]
=n;//最後乙個塊的右區間是n
for(
int i=
1;i<=num;i++
)for
(int
j=l[i]
;j<=r[i]
;j++)}
inline void
update
(int
l,int
r,int
k)else
}inline int
query
(int
l,int
r)else
return ans;
}signed
main()
else
}return0;
}
再來一道分塊題目傳送門hdu4417
題目要求我們求出區間內小於等於h的數的個數。
首先分塊。
我們不能把塊排序因為會改變位置,但我們可以複製乙份,將新的陣列tmp排序,對於每一塊。
對於被包含在區間的塊,只需在tmp中找到臨界的點,它以下的點必定都小於等於h,可以使用upper_bound找到第乙個大於h的數,那麼它以下的數就一定小於等於h了。
對於部分在區間的塊,我們就只能列舉這些數,是否小於等於h,因為排序是對整體進行排序,區域性是無法處理的。
**實現:
#include
using
namespace
std;
const
int n=
1e5+5;
int l[n]
,r[n]
,pos[n]
,tmp[n]
,a[n]
;int
n,m,t;
inline void
build()
}inline int
query
(int
l,int
r,int
h)else
return ans;
}int
main()
}return0;
}
SQL學習筆記 分塊提取查詢結果
實踐中,資料庫中可能有數十億條記錄。查詢結果有可能達到千萬條。如果用dbgetquery 一次性取出所有查詢結果,記憶體可能吃不消。但是,如果容許分塊處理資料來完成任務,那麼下述方法不失為乙個好的選擇。library dbi library rsqlite con dbconnect sqlite ...
筆記 分塊與塊狀陣列
textsf 對於一系列資料,通過適當的劃分,預處理一部分資訊並儲存下來,用空間換取時間,達到時空平衡。核心思想還是暴力。把乙個整體劃分為若干個小塊,對整塊整體處理,零散塊單獨處理。即 大段維護,區域性樸素 事實上,分塊更接近於 樸素 效率往往比不上線段樹和樹狀陣列,但是他更通用,更容易實現。對我這...
分塊 學習筆記
當我們對於乙個很大陣列 1e5 進行區間修改和區間查詢時,我們會想到線段樹的 nlog n 的優秀效率。分塊 優雅的暴力!我們將區間分成每個大小為 s 的小塊,這樣我們的複雜度就會從 n 降到 frac n s 的效率。我們先將陣列分成長度為 s 小塊,用原下標除以 s 向上取整,就是他分塊後的小塊...