《整除分塊》
阿新 • • 發佈:2020-10-14
雖然是一個簡單知識,但整除分塊卻有著很重要的優化作用。
對於 $\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; typedefView Codelong 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; namespaceFASTIO{ 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; }