• 整除分块(数论分块)详解


    整除分块(数论分块)

    介绍

    在求解问题

    [sum_{i=1}^nlfloorfrac ni floor ]

    时,若 (n) 的范围很大那么 (Theta(n)) 求解将会超时,我们需要一种更高效的方法来计算,整除分块就是这样一种方法

    不难发现,在 (i) 取某些值的时候 (lfloorfrac ni floor) 的值都是相同的,考虑将 (lfloorfrac ni floor) 的值相同的 (i) 一起计算,减少计算次数

    那么此时我们需要计算多少次呢?

    (ilesqrt n) 时显然 (lfloorfrac ni floor) 的取值只有 (sqrt n) 种可能,而当 (i>sqrt n) 时有 (frac ni<sqrt n) ,所以 (lfloorfrac ni floor) 的取值同样只有 (sqrt n) 种可能,也就是说 (lfloorfrac ni floor) 的取值只有 (2sqrt n) 种可能,对于同样的取值只用计算一次,总的时间复杂度也就是 (Theta(sqrt n))

    下面来说具体怎么做

    image

    画出 (lfloorfrac ni floor) 的图像不难发现,所有取值相同的 (i) 都是连续的整块的,这也是这个算法叫做整除分块的原因,对于每一块我们想要通过给出这一块的左端点,(Theta(1)) 计算出这一块的右端点,这样才能保证复杂度

    假设现在我们的左端点是 (l),那么设 (lfloorfrac nl floor=k),我们要求右端点也就是最大的 (r=l+d) 使得 (lfloorfrac n{l+d} floor=lfloorfrac nl floor=k)

    (lfloorfrac nl floor)(lfloorfrac n{l+d} floor) 展开得 (n=kl+p)(n=k(l+d)+p'),其中 (1le p<l)

    那么 (kl+p=k(l+d)+p') 所以 (p'=p-kd),因为 (p'ge0),所以 (kdle p),所以 (dlefrac pk),又因为 (d) 为整数,所以 (d) 最大能取 (lfloorfrac pk floor),其中 (p=nmod l=n-llfloorfrac nl floor)(k=lfloorfrac nl floor)

    所以我们有

    [egin{align*} r&=l+d_max\ &=l+lfloorfrac pk floor\ &=l+lfloorfrac{n-llfloorfrac nl floor}{lfloorfrac nl floor} floor\ &=l+lfloorfrac n{lfloorfrac nl floor}-l floor\ &=lfloorfrac n{lfloorfrac nl floor} floor end{align*} ]

    也就是说,对于每一个左端点为 (l) 的块,它的右端点为 (lfloorfrac n{lfloorfrac nl floor} floor)

    (sumlimits_{i=1}^nlfloorfrac ni floor) 我们从左端点 (l)(1) 开始枚举,每次右端点 (r)(min(n,lfloorfrac n{lfloorfrac nl floor} floor)),将答案累加上 ((l-r+1)lfloorfrac nl floor),然后令 (l=r+1) 不断循环,当右端点等于 (n) 时停止循环

    练习

    练习一

    Luogu P3935 Calculating

    题目大意

    给定 (n)(sumlimits_{i=1}^nd(i)),其中 (d(i)) 表示 (i) 的约数个数

    题解

    (1)(n) 的约数显然只能也在 (1)(n) 内,那么考虑换一种方式表达 (sumlimits_{i=1}^nd(i)),枚举 (1)(n) 的所有数,看枚举的数属于多少个数的约数,假设当前枚举到数字 (k) 那么在 (1)(n)(k) 属于多少个数的约数,那么也就是在问在 (1)(n)(k) 的倍数有多少个,显然有 (lfloorfrac nk floor) 个,题目也就转换为了求解 (sumlimits_{i=1}^nlfloorfrac ni floor),整除分块即可

    练习二

    P2261 [CQOI2007]余数求和

    题目大意

    给定 (n,k),求 (sumlimits_{i=1}^nkmod i)

    题解

    (kmod i) 可以写作 (k-ilfloorfrac ki floor),原式即变为 (sumlimits_{i=1}^nk-ilfloorfrac ki floor=kn-sumlimits_{i=1}^nilfloorfrac ki floor),考虑对于 (sumlimits_{i=1}^nilfloorfrac ki floor) 使用整除分块,对于值相同的 (lfloorfrac ki floor),利用等差数列求和公式算出 (i) 的区间和,再乘以 (lfloorfrac ki floor) 就可以 (Theta(1)) 累加进答案

    再看整除分块时 (n,k) 的上界问题,当 (nge k)(i>k) 的部分贡献均为 (0),所以我们忽略 (n)(k) 大的部分,直接以 (k) 为上界计算 (sumlimits_{i=1}^klfloorfrac ki floor) 即可;当 (n<k) 时每次右端点变为 (min(n,lfloorfrac k{lfloorfrac kl floor} floor)),右端点到 (n) 时停止


    该文为本人原创,转载请注明出处

    博客园传送门

  • 相关阅读:
    Shuffle Cards
    求和VII
    Finite Encyclopedia of Integer Sequences(找规律)
    Codeforces Round #223 (Div. 2) C
    Codeforces Round #223 (Div. 2) A
    题目1047:素数判定
    Codeforces Round #219 (Div. 1) C. Watching Fireworks is Fun
    Codeforces Round #219 (Div. 2) B. Making Sequences is Fun
    中南大学第一届长沙地区程序设计邀请赛 New Sorting Algorithm
    中南大学第一届长沙地区程序设计邀请赛 To Add Which?
  • 原文地址:https://www.cnblogs.com/cmy-blog/p/zheng-chu-fen-kuai.html
Copyright © 2020-2023  润新知