把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【洛谷2260】[清华集训2012] 模积和(除法分块)

点此看题面

  • \(\sum_{i=1}^n\sum_{j=1}^m(n\mod i)(m\mod j)[i\not=j]\)
  • \(n,m\le10^9\)

第一步:解除限制

考虑\(i\not=j\)这个限制使得\(i\)\(j\)的贡献不能独立计算,因此我们先容斥处理掉它。

也就是说,用所有情况减去\(i=j\)的情况即为答案,得到下面这个式子:(不妨设\(n\le m\)

\[\sum_{i=1}^n(n\mod i)\times \sum_{j=1}^m(m\mod j)-\sum_{i=1}^{n}(n\mod i)(m\mod i) \]

\(\sum_{i=1}^n(n\mod i)\)

\(\sum_{i=1}^n(n\mod i)\)是一个非常经典的问题。

由于\(n\mod i=n-\lfloor\frac ni\rfloor\times i\),所以原式相当于:

\[\sum_{i=1}^n(n-\lfloor\frac ni\rfloor\times i)=n^2-\sum_{i=1}^n\lfloor\frac ni\rfloor\times i \]

显然后面这一项可以用除法分块轻松搞定。

\(\sum_{j=1}^m(m\mod j)\)同理。

\(\sum_{i=1}^n(n\mod i)(m\mod i)\)

考虑仍旧按照之前的转化,得到:

\[\sum_{i=1}^n(n-\lfloor\frac ni\rfloor\times i)(m-\lfloor\frac mi\rfloor\times i)=n^2m-\sum_{i=1}^n(m\times \lfloor\frac ni\rfloor\times i+n\times \lfloor\frac mi\rfloor\times i-\lfloor\frac ni\rfloor\times \lfloor\frac mi\rfloor\times i^2) \]

后面这家伙也是一个除法分块就能解决的。

综上所述,这道题就用除法分块做完了。

代码:\(O(\sqrt n)\)

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define X 19940417
#define I2 9970209
#define I6 3323403
#define S1(x) (1LL*I2*(x)%X*((x)+1)%X)//1+2+...+x
#define S2(x) (1LL*I6*(x)%X*((x)+1)%X*(2*(x)+1)%X)//1+4+9+...+x^2
using namespace std;
int n,m;
I int Q1(CI n)//求Σ(n%i)
{
	RI t=0;for(RI l=1,r;l<=n;l=r+1) r=n/(n/l),//除法分块
		t=(1LL*(n/l)*(S1(r)-S1(l-1)+X)+t)%X;return (1LL*n*n-t+X)%X;
}
I int Q2(CI n,CI m)//求Σ(n%i)(m%i)
{
	RI t=0;for(RI l=1,r;l<=n;l=r+1) r=min(n/(n/l),m/(m/l)),//除法分块
		t=((1LL*m*(n/l)+1LL*n*(m/l))%X*(S1(r)-S1(l-1)+X)+t)%X,
		t=(t-1LL*(n/l)*(m/l)%X*(S2(r)-S2(l-1)+X)%X+X)%X;
	return (1LL*n*n%X*m%X-t+X)%X;
}
int main()
{
	return scanf("%d%d",&n,&m),n>m&&(n^=m^=n^=m),printf("%d\n",(1LL*Q1(n)*Q1(m)-Q2(n,m)+X)%X),0;//强制n≤m
}
posted @ 2020-10-27 07:52  TheLostWeak  阅读(80)  评论(0编辑  收藏  举报