整除分块
主要就是一些笔记啦!参考的博客和题解:
参考题解
用
途
:
快
速
处
理
形
似
∑
i
=
1
n
⌊
n
i
⌋
的
式
子
用途:快速处理形似\sum_{i=1}^n\lfloor\frac n i\rfloor的式子
用途:快速处理形似i=1∑n⌊in⌋的式子
显然O(n)可以求,但是当数据到了10^10以上,我们就要寻找更优秀的时间复杂度的方法。
观察性质有:
当
⌊
n
i
⌋
=
⌊
n
i
′
⌋
时
,
i
′
的
最
大
取
值
为
⌊
n
⌊
n
i
⌋
⌋
.
.
.
.
.
.
.
(
0
)
但
是
如
何
证
明
(
0
)
式
呢
?
下
面
给
出
(
0
)
式
的
证
明
:
当\lfloor\frac n i\rfloor = \lfloor\frac n {i'}\rfloor时,{i'}的最大取值为\lfloor\frac n {\lfloor\frac n i\rfloor}\rfloor.......(0)\\ 但是如何证明(0)式呢?下面给出(0)式的证明:
当⌊in⌋=⌊i′n⌋时,i′的最大取值为⌊⌊in⌋n⌋.......(0)但是如何证明(0)式呢?下面给出(0)式的证明:
(0)式证明如下:
不
妨
设
⌊
n
i
⌋
=
k
,
则
i
′
的
最
大
取
值
为
⌊
n
k
⌋
(
目
前
是
假
设
i
′
的
最
大
取
值
是
⌊
n
k
⌋
)
不妨设\lfloor\frac n i \rfloor = k,则{i'}的最大取值为\lfloor\frac n k\rfloor\\(目前是假设{i'}的最大取值是\lfloor\frac n k\rfloor)
不妨设⌊in⌋=k,则i′的最大取值为⌊kn⌋(目前是假设i′的最大取值是⌊kn⌋)
而 ⌊ n i ⌋ 单 调 递 减 , 所 以 只 要 证 明 : i ′ = k 时 满 足 ⌊ n ⌊ n k ⌋ ⌋ = k . . . . . . ( 1 ) 再 证 明 : i ′ = k 时 满 足 ⌊ n ⌊ n k ⌋ + 1 ⌋ < k . . . . . ( 2 ) 即 可 严 格 证 明 i = k 时 满 足 ⌊ n k ⌋ 是 满 足 条 件 最 大 的 i 先 证 明 ( 1 ) 式 : ∵ ⌊ n k ⌋ < = n k ∴ n ⌊ n k ⌋ > = n n k = k ∴ ⌊ n ⌊ n k ⌋ ⌋ > = k ( 1 ) 式 得 证 . 再 证 明 ( 2 ) 式 : 显 然 只 要 证 得 n ⌊ n k ⌋ + 1 < k 则 ( 2 ) 式 得 证 , 只 需 证 明 : k ∗ ⌊ n k ⌋ + k > n 由 带 余 除 法 : n = q ∗ k + r , 0 < = r < k ∴ k ∗ q + k > n 而 n = q ∗ k + r , 且 0 < = r < k ∴ ( 2 ) 式 得 证 综 上 所 述 : ( 0 ) 式 得 证 而\lfloor\frac n i\rfloor单调递减,所以\\只要证明:{i'}=k时满足\lfloor\frac n {\lfloor\frac n k\rfloor}\rfloor = k\space\space ......(1)\\再证明:{i'}=k时满足\lfloor\frac n {\lfloor\frac n k\rfloor+1}\rfloor < k.....(2) \\即可严格证明i=k时满足\lfloor\frac n k\rfloor 是满足条件最大的i \\先证明(1)式:\\ \because\lfloor\frac n k\rfloor<=\frac n k\\ \therefore\frac n{\lfloor\frac n k\rfloor}>=\frac n {\frac n k} = k\\ \therefore\lfloor\frac n{\lfloor\frac n k\rfloor}\rfloor>=k\\ (1)式得证.再证明(2)式:\\显然只要证得\frac n {\lfloor\frac n k\rfloor+1}<k\space\space 则(2)式得证,\\只需证明:k*\lfloor\frac n k\rfloor+k>n\\由带余除法: n = q*k+r,0<=r<k\\ \therefore k*q+k>n\\而 n = q*k+r,且0<=r<k\\ \therefore (2)式得证 \\\\ 综上所述:(0)式得证 而⌊in⌋单调递减,所以只要证明:i′=k时满足⌊⌊kn⌋n⌋=k ......(1)再证明:i′=k时满足⌊⌊kn⌋+1n⌋<k.....(2)即可严格证明i=k时满足⌊kn⌋是满足条件最大的i先证明(1)式:∵⌊kn⌋<=kn∴⌊kn⌋n>=knn=k∴⌊⌊kn⌋n⌋>=k(1)式得证.再证明(2)式:显然只要证得⌊kn⌋+1n<k 则(2)式得证,只需证明:k∗⌊kn⌋+k>n由带余除法:n=q∗k+r,0<=r<k∴k∗q+k>n而n=q∗k+r,且0<=r<k∴(2)式得证综上所述:(0)式得证
代码:
例题1
typedef long long ll;
ll divide_block(ll n)
{
ll res = 0;
for(ll i = 1,j;i<=n;i=j+1)
{
j = n/(n/i);
res += (j-i+1)*(n/i);
}
return res;
}
例题1
CQOI2007 余数之和
求
∑
i
=
1
n
k
m
o
d
i
求\sum_{i=1}^nk\space mod \space i
求i=1∑nk mod i
分 析 : 乍 一 看 m o d 和 n / i 并 没 有 什 么 关 系 , 但 是 可 以 展 开 有 : ∑ i = 1 n k − ⌊ k i ⌋ ∗ i = n ∗ k − ∑ i = 1 n ⌊ k i ⌋ ∗ i 而 我 们 已 经 O ( n ) 可 以 处 理 ∑ i = 1 n n i 这 里 只 需 要 考 虑 如 何 处 理 ∑ i = 1 n ⌊ k i ⌋ ∗ i 而 对 于 一 个 整 除 分 块 ∑ i = l r ⌊ k i ⌋ , 其 中 的 每 个 值 都 是 相 同 的 那 么 不 妨 设 T = ⌊ k i ⌋ 则 原 式 = n ∗ k − ( ∑ i = l r ( T ⋅ i ) ) 分析:乍一看mod和n/i并没有什么关系,但是可以展开有:\\ \sum_{i=1}^nk-\lfloor\frac k i\rfloor*i =n*k-\sum_{i=1}^n\lfloor\frac k i\rfloor*i\\ 而我们已经O(\sqrt n)可以处理\sum_{i=1}^n\frac n i\\ 这里只需要考虑如何处理\sum_{i=1}^n\lfloor\frac k i \rfloor*i \\而对于一个整除分块\sum_{i=l}^r\lfloor\frac k i\rfloor,其中的每个值都是相同的 \\那么不妨设T = \lfloor \frac k i \rfloor \\则原式 = n*k-(\sum_{i=l}^r(T\cdot i)) 分析:乍一看mod和n/i并没有什么关系,但是可以展开有:i=1∑nk−⌊ik⌋∗i=n∗k−i=1∑n⌊ik⌋∗i而我们已经O(n)可以处理i=1∑nin这里只需要考虑如何处理i=1∑n⌊ik⌋∗i而对于一个整除分块i=l∑r⌊ik⌋,其中的每个值都是相同的那么不妨设T=⌊ik⌋则原式=n∗k−(i=l∑r(T⋅i))
代码:
typedef long long ll;
ll divide_block(ll n,ll k)
{
ll ans = n*k;//根据公式来
for(ll i = 1,j;i<=n;i=j+1)
{
if(k/i!=0)
{
j = min(k/(k/i),n);//i到j之间最多是n项,最少是k/(k/i)项
}
else
{
j = n;
}
ans -= (k/i)*(j-i+1)*(i+j)/2;//由推导的公式而来
//等价于ans-=(k/i)*(j-i+1)+(i+j)/2*(j-i+1)
//代码只是合并注释的同类项
}
return ans;
}
后续更新其他例题~