zoukankan      html  css  js  c++  java
  • 整除分块(数论分块)详解

    整除分块(数论分块)

    介绍

    在求解问题

    [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) 时停止


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

    博客园传送门

  • 相关阅读:
    hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
    hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
    hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
    hdu6441 Find Integer 求勾股数 费马大定理
    bzoj 1176 Mokia
    luogu 3415 祭坛
    bzoj 1010 玩具装箱
    bzoj 3312 No Change
    luogu 3383【模板】线性筛素数
    bzoj 1067 降雨量
  • 原文地址:https://www.cnblogs.com/cmy-blog/p/zheng-chu-fen-kuai.html
Copyright © 2011-2022 走看看