整除分块入门

整除分块

首先引入一个问题,若我们要求这么一个式子:
∑ i = 1 n ⌊ n i ⌋ \sum\limits_{i=1}^{n} \left\lfloor\dfrac{n}{i}\right\rfloor i=1nin
自然而然会想到这么一段翻译代码:

for(int i=1;i<=n;i++)
  sum+=n/i;

但是,如果 1 ≤ n ≤ 1 0 9 1\le n\le10^9 1n109,又该如何解决呢?

显然, ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in n i \dfrac{n}{i} in的不同在于,前者的值在某些情况下会出现区间性的大量重复。
下面我们来考察当 n = 10 n=10 n=10 ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in的取值

10 5 3 2 2 1 1 1 1 1 \boxed{10}\quad \boxed{5}\quad \boxed{3}\quad \boxed{2\quad 2}\quad \boxed{1\quad 1\quad 1\quad 1\quad 1} 10532211111
我们可以发现:
⌊ n 1 ⌋ = 10   ⌊ n 2 ⌋ = 5   ⌊ n 3 ⌋ = 3   ⌊ n 4 ⌋ = ⌊ n 5 ⌋ = 2   ⌊ n 6 ⌋ = ⌊ n 7 ⌋ = ⌊ n 8 ⌋ = ⌊ n 9 ⌋ = ⌊ n 10 ⌋ = 1 \left\lfloor\dfrac{n}{1}\right\rfloor=10\\ ~\\ \left\lfloor\dfrac{n}{2}\right\rfloor=5\\ ~\\ \left\lfloor\dfrac{n}{3}\right\rfloor=3\\ ~\\ \left\lfloor\dfrac{n}{4}\right\rfloor=\left\lfloor\dfrac{n}{5}\right\rfloor=2\\ ~\\ \left\lfloor\dfrac{n}{6}\right\rfloor=\left\lfloor\dfrac{n}{7}\right\rfloor=\left\lfloor\dfrac{n}{8}\right\rfloor=\left\lfloor\dfrac{n}{9}\right\rfloor=\left\lfloor\dfrac{n}{10}\right\rfloor=1 1n=10 2n=5 3n=3 4n=5n=2 6n=7n=8n=9n=10n=1
显然重复部分(我们将他们成为块)占比很大,因此我们就找到了优化的突破口,如何优化在重复部分耗费的计算?

由于 i i i 单调递增排列,因此重复部分是连续出现的,对于一个块 [ l , r ] [l,r] [l,r],若求出了 l , r l,r l,r就可以快速计算一整个块整除意义上的贡献。

经过思考可以得到 l l l的初值必定为 1 1 1,还有一个很显然的 l l l 的转移方程:
l = r + 1 l=r+1 l=r+1
此时问题再次简单化,如何在已知 l l l的情况下,快速求出重复部分右端点 r r r

考虑 r r r的性质:根据 [ l , r ] [l,r] [l,r]的定义可以得到 ⌊ n l ⌋ = ⌊ n r ⌋ \left\lfloor\dfrac{n}{l}\right\rfloor=\left\lfloor\dfrac{n}{r}\right\rfloor ln=rn,我们将 ⌊ n l ⌋ \left\lfloor\dfrac{n}{l}\right\rfloor ln表示为 k k k
此时有:
k = ⌊ n r ⌋   n r ≥ k   ( 向 下 取 整 必 定 小 于 分 数 运 算 )   r n ≤ 1 k   r ≤ ⌊ n k ⌋ ( r ∈ Z ) k=\left\lfloor\dfrac{n}{r}\right\rfloor\\ ~\\ \dfrac{n}{r}\ge k~(向下取整必定小于分数运算)\\ ~\\ \dfrac{r}{n}\le \dfrac{1}{k}\\ ~\\ r\le \left\lfloor\dfrac{n}{k}\right\rfloor (r\in\Z) k=rn rnk  nrk1 rkn(rZ)
此时若使 r r r 最大,则取等,即 r = ⌊ n k ⌋ = ⌊ n ⌊ n l ⌋ ⌋ r=\left\lfloor\dfrac{n}{k}\right\rfloor=\left\lfloor\dfrac{n}{\left\lfloor\dfrac{n}{l}\right\rfloor}\right\rfloor r=kn=lnn
此时,我们已经得到了快速求出 l , r l,r l,r的算法,因此对于大量的重复贡献,我么可以利用 [ l , r ] [l,r] [l,r]区间快速得到总贡献,时间复杂度为 Θ ( n ) \Theta(\sqrt{n}) Θ(n )
具体实现请看代码:

for(int l=1,r;l<=n;l=r+1)
{
  int k=n/l;
  r=n/k;
  sum=sum+(k*(r-l+1));  //相同贡献乘区间长度
}

我们习惯把以上优化算法称为整除分块(或除法分块、数论分块等),它可以优化以下类似式子的时间复杂度:
∑ i = 1 n f ( ⌊ n i ⌋ ) \sum\limits_{i=1}^{n}f(\left\lfloor\dfrac{n}{i}\right\rfloor) i=1nf(in)


例题深化

1. UVA11526

模板题,翻译都不需要的那种,直接整除分块优化。(过~~~)

2.P3935 Calculating

题目大意:求
若 n = p 1 c 1 ⋅ p 2 c 2 ⋯ p m c m , f ( n ) = ( c 1 + 1 ) ⋅ ( c 2 + 1 ) ⋯ ( c m + 1 )   ∑ i = l r f ( i )     m o d   998244353 若n=p_1^{c_1}\cdot p_2^{c_2}\cdots p_m^{c_m},f(n)=(c_1+1)\cdot(c_2+1)\cdots(c_m+1)\\ ~\\ \sum\limits_{i=l}^{r}f(i)~\bmod998244353\\ n=p1c1p2c2pmcm,f(n)=(c1+1)(c2+1)(cm+1) i=lrf(i) mod998244353

首先我们要知道 n = p 1 c 1 ⋅ p 2 c 2 ⋯ p m c m , 则 f ( n ) = ( c 1 + 1 ) ⋅ ( c 2 + 1 ) ⋯ ( c m + 1 ) n=p_1^{c_1}\cdot p_2^{c_2}\cdots p_m^{c_m},则f(n)=(c_1+1)\cdot(c_2+1)\cdots(c_m+1) n=p1c1p2c2pmcm,f(n)=(c1+1)(c2+1)(cm+1)即为 n n n的因数个数,可以由质因数的组合得到这个公式,这里不再详解。

回顾到这道题,要求区间 [ l , r ] [l,r] [l,r]中的数的因子个数之和,自然而然就是类似于前缀和式的方法:求出 [ 1 , l − 1 ] [1,l-1] [1,l1]的因子和以及 [ 1 , r ] [1,r] [1,r]的因子和,然后后者减去前者,就可以得到 [ l , r ] [l,r] [l,r]的因子和。

可以知道, [ 1 , n ] [1,n] [1,n] i i i的倍数有 ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in个,即有 ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in个数包含因子 i i i。因此 ∑ i = 1 n f ( i ) = ∑ i = 1 n ⌊ n i ⌋ \sum\limits_{i=1}^{n}f(i)=\sum\limits_{i=1}^{n}\left\lfloor\dfrac{n}{i}\right\rfloor i=1nf(i)=i=1nin

∑ i = l r f ( i ) = ∑ i = 1 r ⌊ r i ⌋ − ∑ i = 1 l − 1 ⌊ l i ⌋ \sum\limits_{i=l}^{r}f(i)=\sum\limits_{i=1}^{r}\left\lfloor\dfrac{r}{i}\right\rfloor-\sum\limits_{i=1}^{l-1}\left\lfloor\dfrac{l}{i}\right\rfloor i=lrf(i)=i=1riri=1l1il

然后又变成了整除分块裸题。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD=998244353;
int a,b;
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
    cin>>a>>b;
    int suma=0,sumb=0;
    for(int l=1,r;l<=(a-1);l=r+1)
    {
      r=(a-1)/((a-1)/l);
      suma=(suma+(((a-1)/l)%MOD*(r-l+1)%MOD)%MOD)%MOD;
    }
    for(int l=1,r;l<=b;l=r+1)
    {
      r=b/(b/l);
      sumb=(sumb+((b/l)%MOD*(r-l+1)%MOD)%MOD)%MOD;
    }
    cout<<((sumb-suma)%MOD+MOD)%MOD;
	return 0;
}

3.CF616E Sum of Remainders

题目大意:

( ∑ i = 1 m n   m o d   i )   m o d   ( 1 0 9 + 7 ) (\sum\limits_{i=1}^{m}n\bmod i)\bmod (10^9+7) (i=1mnmodi)mod(109+7)

很简单的一道推式子题,就是因为用上了整除分块才水上了紫。
∑ i = 1 m n   m o d   i = ∑ i = 1 m ( n − ⌊ n i ⌋ ⋅ i ) = n m − ∑ i = 1 m ⌊ n i ⌋ ⋅ i \sum\limits_{i=1}^{m}n\bmod i=\sum\limits_{i=1}^{m}(n-\left\lfloor\dfrac{n}{i}\right\rfloor\cdot i)=nm-\sum\limits_{i=1}^{m}\left\lfloor\dfrac{n}{i}\right\rfloor\cdot i i=1mnmodi=i=1m(nini)=nmi=1mini
由于块中的元素重复,我们可以提取公因数,因此乘 i i i可以在整除分块的过程中执行,不会影响效率, ∑ i = 1 m ⌊ n i ⌋ i \sum\limits_{i=1}^{m}\left\lfloor\dfrac{n}{i}\right\rfloor i i=1mini可以利用整除分块和高斯求和公式快速得到(不懂得可以停下来稍微想想)。

照水不误

  • 运算过程中会爆longlong,取余很恶心
  • 在这种恶心超大取余数论题中,常要预处理出某些除数的乘法逆元。
#include <bits/stdc++.h>
#define int long long
#define inv2 500000004//2在mod 1e9+7 意义下的乘法逆元
using namespace std;
int n,m;
int ans;
const int MOD=1e9+7;
signed main()
{
  cin>>n>>m;
  ans=((n%MOD)*(m%MOD))%MOD;
  int sum=0;
  for(int l=1,r;l<=min(n,m);l=r+1)
  {
    r=n/(n/l);
    if(r>m) r=m;
    sum=(1ll*sum%MOD+(1ll*(n/l)%MOD*((((r-l+1)%MOD)*((r+l)%MOD))%MOD*inv2%MOD)%MOD)%MOD)%MOD;
  }
  cout<<((ans-sum%MOD)%MOD+MOD)%MOD;
  return 0;
}

4.P2260 [清华集训2012]模积和

题目大意:
∑ i = 1 n ∑ j = 1 m ( n   m o d   i ) ⋅ ( m   m o d   j )    i ≠ j \sum\limits_{i=1}^{n}\sum\limits_{j=1}^m(n\bmod i)\cdot(m\bmod j)~~i\ne j i=1nj=1m(nmodi)(mmodj)  i=j
  m o d   19940417 \bmod 19940417 mod19940417的值

对于这种式子很长,没有思路的题目,往往需要我们将式子拆开来才能找到考点。
考虑式子条件 i ≠ j i\ne j i=j的运算意义,就是在原有式子的基础上减去 i , j i,j i,j重复部分,即
∑ i = 1 n ∑ j = 1 m ( n   m o d   i ) ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) ( n   m o d   i ) ( m   m o d   i ) \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}(n \bmod i)(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}(n\bmod i)(m\bmod i) i=1nj=1m(nmodi)(mmodj)i=1min(n,m)(nmodi)(mmodi)
然后我们就可以愉快的手撕 ∑ \sum :
∑ i = 1 n ∑ j = 1 m ( n   m o d   i ) ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) ( n   m o d   i ) ( m   m o d   i ) ⇔ ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) ( n   m o d   i ) ( m   m o d   i ) ⇔ ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) ( n − ⌊ n i ⌋ ⋅ i ) ( m − ⌊ m i ⌋ ⋅ i ) ⇔ ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) ( n m − m ⋅ ⌊ n i ⌋ ⋅ i − n ⋅ ⌊ m i ⌋ ⋅ i + ⌊ m i ⌋ ⌊ n i ⌋ ⋅ i 2 ) ⇔ ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − ∑ i = 1 min ⁡ ( n , m ) n m + ∑ i = 1 min ⁡ ( n , m ) m ⌊ n i ⌋ i + ∑ i = 1 min ⁡ ( n , m ) n ⌊ m i ⌋ i − ∑ i = 1 min ⁡ ( n , m ) ⌊ m i ⌋ ⌊ n i ⌋ i 2 \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}(n \bmod i)(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}(n\bmod i)(m\bmod i)\\ \Leftrightarrow\\ \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}(n\bmod i)(m\bmod i)\\ \Leftrightarrow\\ \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}(n-\left\lfloor\dfrac{n}{i}\right\rfloor\cdot i)(m-\left\lfloor\dfrac{m}{i}\right\rfloor\cdot i)\\ \Leftrightarrow\\ \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}(nm-m\cdot\left\lfloor\dfrac{n}{i}\right\rfloor\cdot i-n\cdot\left\lfloor\dfrac{m}{i}\right\rfloor\cdot i+\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor\cdot i^2)\\ \Leftrightarrow\\ \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-\sum\limits_{i=1}^{\min(n,m)}nm+\sum\limits_{i=1}^{\min(n,m)}m\left\lfloor\dfrac{n}{i}\right\rfloor i+\sum\limits_{i=1}^{\min(n,m)}n\left\lfloor\dfrac{m}{i}\right\rfloor i-\sum\limits_{i=1}^{\min(n,m)}\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor i^2 i=1nj=1m(nmodi)(mmodj)i=1min(n,m)(nmodi)(mmodi)i=1n(nmodi)j=1m(mmodj)i=1min(n,m)(nmodi)(mmodi)i=1n(nmodi)j=1m(mmodj)i=1min(n,m)(nini)(mimi)i=1n(nmodi)j=1m(mmodj)i=1min(n,m)(nmmininimi+imini2)i=1n(nmodi)j=1m(mmodj)i=1min(n,m)nm+i=1min(n,m)mini+i=1min(n,m)nimii=1min(n,m)imini2
我们使 m < n m<n m<n:
∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − ∑ i = 1 m n m + ∑ i = 1 m m ⌊ n i ⌋ i + ∑ i = 1 m n ⌊ m i ⌋ i − ∑ i = 1 m ⌊ m i ⌋ ⌊ n i ⌋ i 2 ⇔ ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) − n m 2 + m ∑ i = 1 m ⌊ n i ⌋ i + n ∑ i = 1 m ⌊ m i ⌋ i − ∑ i = 1 m ⌊ m i ⌋ ⌊ n i ⌋ i 2 \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-\sum\limits_{i=1}^{m}nm+\sum\limits_{i=1}^{m}m\left\lfloor\dfrac{n}{i}\right\rfloor i+\sum\limits_{i=1}^{m}n\left\lfloor\dfrac{m}{i}\right\rfloor i-\sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor i^2\\ \Leftrightarrow\\ \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j)-nm^2+m\sum\limits_{i=1}^{m}\left\lfloor\dfrac{n}{i}\right\rfloor i+n\sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor i-\sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor i^2 i=1n(nmodi)j=1m(mmodj)i=1mnm+i=1mmini+i=1mnimii=1mimini2i=1n(nmodi)j=1m(mmodj)nm2+mi=1mini+ni=1mimii=1mimini2
这个式子结构性就很强了,我们可以考虑逐一求得式子各部分的值来得到最终答案。

  • part 1: ∑ i = 1 n ( n   m o d   i ) ∑ j = 1 m ( m   m o d   j ) \sum\limits_{i=1}^{n}(n\bmod i)\sum\limits_{j=1}^{m}(m\bmod j) i=1n(nmodi)j=1m(mmodj)
    很显然就是上一题的结论与做法,不再赘述。

  • part 2: n m 2 nm^2 nm2
    入门级运算

  • part 3: m ∑ i = 1 m ⌊ n i ⌋ i + n ∑ i = 1 m ⌊ m i ⌋ i m\sum\limits_{i=1}^m\left\lfloor\dfrac{n}{i}\right\rfloor i+n\sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor i mi=1mini+ni=1mimi
    依旧是上一题结论,换汤不换药。

  • part 4: ∑ i = 1 m ⌊ m i ⌋ ⌊ n i ⌋ i 2 \sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor i^2 i=1mimini2

看到这个式子我一开始就蒙了(太弱了),是不是式子柴得不够完全啊,然后就浪费了大量的时间来化简这个式子,最后还是做了无用功。

那到底应该如何处理呢?观察这部分式子, ⌊ m i ⌋ \left\lfloor\dfrac{m}{i}\right\rfloor im ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in都是我们熟悉的整除分块,但是要是将他们联系在一起 ⌊ m i ⌋ ⌊ n i ⌋ \left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor imin显然不是简单的直接分块相乘,那又该如何优化呢?借助上一题的思路,利用块的优化过程自然也要带上计算 i 2 i^2 i2,那是否 ∑ i = 1 n i 2 \sum\limits_{i=1}^{n}i^2 i=1ni2也具有类似等差数列一样的求和公式呢(我太弱了不知道,在教练的帮助下推了好久才推出来)?

我们来模拟一下 ∑ i = 1 m ⌊ m i ⌋ ⌊ n i ⌋ \sum\limits_{i=1}^{m}\left\lfloor\dfrac{m}{i}\right\rfloor\left\lfloor\dfrac{n}{i}\right\rfloor i=1mimin的过程,考虑 n = 20 , m = 17 n=20,m=17 n=20,m=17

20 ⋅ 17 10 ⋅ 8 6 ⋅ 5 5 ⋅ 4 4 ⋅ 3 3 ⋅ 2 2 ⋅ 2 2 ⋅ 2 2 ⋅ 1 2 ⋅ 1   1 ⋅ 1 1 ⋅ 1 1 ⋅ 1 1 ⋅ 1 1 ⋅ 1 1 ⋅ 1 1 ⋅ 1 \boxed{20\cdot 17}\quad\boxed{10\cdot 8}\quad\boxed{6\cdot5}\quad\boxed{5\cdot 4}\quad\boxed{4\cdot 3}\quad\boxed{3\cdot 2}\quad\boxed{2\cdot 2\quad 2\cdot 2}\quad\boxed{2\cdot 1\quad2\cdot 1}\\ ~\\ \boxed{1\cdot 1\quad1\cdot 1\quad1\cdot 1\quad1\cdot 1\quad1\cdot 1\quad1\cdot 1\quad1\cdot 1} 20171086554433222222121 11111111111111

稍加思索可以发现, ⌊ n i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor in所分的一个块与 ⌊ m i ⌋ \left\lfloor\dfrac{m}{i}\right\rfloor im所分的一个块的交集(公共部分)也是 ⌊ n i ⌋ ⌊ m i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor inim的一个块

稍微数学一点的表达:
若 A 为 ⌊ n i ⌋ 的 一 个 块 , B 为 ⌊ m i ⌋ 的 一 个 快   记 作   A ∈ ⌊ n i ⌋ , B ∈ ⌊ m i ⌋   则 有   ( A ∩ B ) ∈ ⌊ n i ⌋ ⌊ m i ⌋ 若A为\left\lfloor\dfrac{n}{i}\right\rfloor的一个块,B为\left\lfloor\dfrac{m}{i}\right\rfloor的一个快\\ ~\\ 记作~A\in\left\lfloor\dfrac{n}{i}\right\rfloor,B\in\left\lfloor\dfrac{m}{i}\right\rfloor\\ ~\\ 则有~(A\cap B)\in \left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor AinBim  AinBim  (AB)inim
有了这个概念,我们就易得 ⌊ n i ⌋ ⌊ m i ⌋ \left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor inim的块 [ l , r ] [l,r] [l,r]的左右端点转移方程:
{ r = min ⁡ ( ⌊ n ⌊ n l ⌋ ⌋ , ⌊ m ⌊ m l ⌋ ⌋ )   l = r + 1 \begin{cases} r=\min(\left\lfloor\dfrac{n}{\left\lfloor\dfrac{n}{l}\right\rfloor}\right\rfloor,\left\lfloor\dfrac{m}{\left\lfloor\dfrac{m}{l}\right\rfloor}\right\rfloor)\\ ~\\ l=r+1 \end{cases} r=min(lnn,lmm) l=r+1

接下来我们考虑推导 S n = ∑ i = 1 n i 2 S_n=\sum\limits_{i=1}^ni^2 Sn=i=1ni2 的通项式。

考虑
∵ ( n + 1 ) 3 = n 3 + 3 n 2 + 3 n + 1   ∴ ( n + 1 ) 3 − n 3 = 3 n 2 + 3 n + 1   ∴ { 2 3 − 1 3 = 3 ⋅ 1 2 + 3 + 1 = 7 3 3 − 2 3 = 3 ⋅ 2 2 + 3 ⋅ 2 + 1 = 19 4 3 − 3 3 = 3 ⋅ 3 2 + 3 ⋅ 3 + 1 = 37 ⋯ ( n + 1 ) 3 − n 3 = 3 n 2 + 3 n + 1   ∴ ( n + 1 ) 3 − 1 3 = ∑ i = 1 n ( ( i + 1 ) 3 − i 3 ) = 3 ∑ i = 1 n n 2 + 3 ∑ i = 1 n i + ∑ i = 1 n 1 = 3 ⋅ S n + 3 ⋅ ( n + 1 ) n 2 + n ∴ S n = ( n + 1 ) 3 3 − 1 3 − ( n + 1 ) n 2 − n 3 = 2 ( n + 1 ) 3 6 − 2 6 − 3 ( n + 1 ) n 6 − 2 n 6 = 2 ( n + 1 ) 3 − 2 − 3 ( n + 1 ) n − 2 n 6 = 2 n 3 + 6 n 2 + 6 n + 2 − 2 − 3 n 2 − 3 n − 2 n 6 = 2 n 3 + 3 n 2 + n 6 = n ( n + 1 ) ( 2 n + 1 ) 6      ( 提 取 公 因 数 后 再 十 字 相 乘 化 简 ) \because(n+1)^3=n^3+3n^2+3n+1\\ ~\\ \therefore(n+1)^3-n^3=3n^2+3n+1\\ ~\\ \therefore \begin{cases} 2^3-1^3=3\cdot 1^2+3+1=7\\ 3^3-2^3=3\cdot 2^2+3\cdot 2+1=19\\ 4^3-3^3=3\cdot3^2+3\cdot3+1=37\\ \cdots\\ (n+1)^3-n^3=3n^2+3n+1 \end{cases}\\ ~\\ \therefore\begin{aligned} (n+1)^3-1^3&=\sum\limits_{i=1}^{n}\left((i+1)^3-i^3\right)\\ &=3\sum\limits_{i=1}^{n}n^2+3\sum\limits_{i=1}^{n}i+\sum\limits_{i=1}^n1\\ &=3\cdot S_n+3\cdot\dfrac{(n+1)n}{2}+n \end{aligned}\\ \therefore\begin{aligned} S_n&=\dfrac{(n+1)^3}{3}-\dfrac{1}{3}-\dfrac{(n+1)n}{2}-\dfrac{n}{3}\\ &=\dfrac{2(n+1)^3}{6}-\dfrac{2}{6}-\dfrac{3(n+1)n}{6}-\dfrac{2n}{6}\\ &=\dfrac{2(n+1)^3-2-3(n+1)n-2n}{6}\\ &=\dfrac{2n^3+6n^2+6n+2-2-3n^2-3n-2n}{6}\\ &=\dfrac{2n^3+3n^2+n}{6}\\ &=\dfrac{n(n+1)(2n+1)}{6}~~~~(提取公因数后再十字相乘化简)\\ \end{aligned} (n+1)3=n3+3n2+3n+1 (n+1)3n3=3n2+3n+1 2313=312+3+1=73323=322+32+1=194333=332+33+1=37(n+1)3n3=3n2+3n+1 (n+1)313=i=1n((i+1)3i3)=3i=1nn2+3i=1ni+i=1n1=3Sn+32(n+1)n+nSn=3(n+1)3312(n+1)n3n=62(n+1)36263(n+1)n62n=62(n+1)323(n+1)n2n=62n3+6n2+6n+223n23n2n=62n3+3n2+n=6n(n+1)(2n+1)    ()

此时,我们已经解决了关于这道题的所有难点,有了二维整除分块以及 ∑ i = 1 n i 2 \sum\limits_{i=1}^ni^2 i=1ni2的求和公式,我么就可仿照类似上一题一般的方法优化 ∑ i = 1 m ⌊ n i ⌋ ⌊ m i ⌋ i 2 \sum\limits_{i=1}^m\left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor i^2 i=1minimi2

此时,我们首先化简题目的式子,然后对式子各部分进行逐一处理优化,最后得到了最终的算法:

处理以下函数

  • F x : ∑ i = 1 x ( x   m o d   i ) F_x:\sum\limits_{i=1}^x(x\bmod i) Fxi=1x(xmodi)
  • G x , y : ∑ i = 1 x ( y   m o d   i ) G_{x,y} :\sum\limits_{i=1}^x(y\bmod i) Gx,yi=1x(ymodi)
  • T : ∑ i = 1 m ⌊ n i ⌋ ⌊ m i ⌋ i 2 T:\sum\limits_{i=1}^m\left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor i^2 Ti=1minimi2

最终答案为: F n F m − n m 2 + n G m , m + m G m , n − T F_nF_m-nm^2+nG_{m,m}+mG_{m,n}-T FnFmnm2+nGm,m+mGm,nT

#include<bits/stdc++.h>
#define int long long
const long long MOD=19940417,inv6=3323403,inv2=9970209;  //预处理公式中除数的乘法逆元
using namespace std;
int n,m;
int G(int s,int t)
{
  int sum=0;
  for(int l=1,r;l<=s;l=r+1)
  {
    r=min(t/(t/l),s);
    sum=(sum+1ll*(t/l)*(r+l)%MOD*(r-l+1)%MOD*inv2)%MOD;
  }
  return sum%MOD;
}
int F(int s)
{
  return (1ll*s*s-G(s,s))%MOD;
}
int S(int s)
{
  return 1ll*s*(s+1)%MOD*(s+s+1)%MOD*inv6%MOD;
}
int ans()
{
  int a;
  a=1ll*F(n)*F(m)%MOD;
  a=(a+1ll*n*G(m,m)+1ll*m*G(m,n))%MOD;
  a=1ll*(a-1ll*m*m%MOD*n)%MOD;
  return a;
}
int T()
{
  int sum=ans();
  for(int l=1,r;l<=m;l=r+1)
  {
    r=min(n/(n/l),m/(m/l));
    sum=(sum-1ll*((n/l)%MOD*(m/l))%MOD*(S(r)-S(l-1))%MOD)%MOD;
  }
  return (sum%MOD+MOD)%MOD;
}
signed main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin>>n>>m;
  if(m>n) swap(m,n);
  cout<<T();
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值