1. 程式人生 > 實用技巧 >《整除分塊》

《整除分塊》

雖然是一個簡單知識,但整除分塊卻有著很重要的優化作用。

對於 $\sum_{i = 1}^{n}[\frac{n}{i}]$的求解。

當n很大時,O(n)的複雜度顯然不能接受,於是就有了整除分塊。

對暴力的值適當打表,可以發現,整除後的值都是呈塊狀分佈的,並且這些塊的大小,會越來越大。

且,我們可以發現,如果當前塊的起始位置為L,那麼他的終止位置即為,r = n / (n / L),那麼塊的大小即為r - L + 1.

需要注意的是,塊的值應該是n / L。

至此可以推得O($\sqrt{n}$)的做法。

#include<bits/stdc++.h>
using namespace std;
typedef 
long long LL; typedef pair<double,int> pii; const int N = 1e6+5; const int M = 1e6+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e9 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace
FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){
if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; int main() { LL n;n = read(); LL sum = 0; for(int L = 1,r = 0;L <= n;L = r + 1) { r = n / (n / L); sum += (n / L) * (r - L + 1); } dbg(sum); system("pause"); return 0; }
View Code