数学题
推式子:
∑i=1n∑j=1m(n mod i)×(m mod j)(i≠j)
∑
i
=
1
n
∑
j
=
1
m
(
n
m
o
d
i
)
×
(
m
m
o
d
j
)
(
i
≠
j
)
∑i=1n(n mod i)×∑j=1m(m mod j)−∑i=1min(n,m)(n mod i)×(m mod i)
∑
i
=
1
n
(
n
m
o
d
i
)
×
∑
j
=
1
m
(
m
m
o
d
j
)
−
∑
i
=
1
m
i
n
(
n
,
m
)
(
n
m
o
d
i
)
×
(
m
m
o
d
i
)
∑i=1n(n−i⌊ni⌋)∑j=1m(m−j⌊mj⌋)−∑i=1min(n,m)(n−i⌊ni⌋)(m−i⌊mi⌋)
∑
i
=
1
n
(
n
−
i
⌊
n
i
⌋
)
∑
j
=
1
m
(
m
−
j
⌊
m
j
⌋
)
−
∑
i
=
1
m
i
n
(
n
,
m
)
(
n
−
i
⌊
n
i
⌋
)
(
m
−
i
⌊
m
i
⌋
)
∑i=1n(n−i⌊ni⌋)∑j=1m(m−j⌊mj⌋)−∑i=1min(n,m)(nm+⌊ni⌋⌊mi⌋i2−(m⌊ni⌋+n⌊mi⌋)i)
∑
i
=
1
n
(
n
−
i
⌊
n
i
⌋
)
∑
j
=
1
m
(
m
−
j
⌊
m
j
⌋
)
−
∑
i
=
1
m
i
n
(
n
,
m
)
(
n
m
+
⌊
n
i
⌋
⌊
m
i
⌋
i
2
−
(
m
⌊
n
i
⌋
+
n
⌊
m
i
⌋
)
i
)
减号前面的直接像余数之和一样搞一搞,后面的除法分块算一下就好了。
有一个公式: ∑ni=1i2=n(n+1)(2n+1)6 ∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inv 3323403
#define MOD 19940417
#define F inline
using namespace std;
typedef long long LL;
LL n,m,ans,p1,p2,p3;
F LL ca(LL x,LL y){ return (y-x+1)*(x+y)/2%MOD; }
F LL cal(LL x){ return x*(x+1)%MOD*(x*2+1)%MOD*inv%MOD; }
F LL calc(LL x){
LL ret=0;
for (LL l=1,r;l<=x;l=r+1)
r=x/(x/l),ret=(ret+x*(r-l+1)%MOD-ca(l,r)*(x/l))%MOD;
return (ret+MOD)%MOD;
}
int main(){
scanf("%lld%lld",&n,&m);
ans=calc(n)*calc(m)%MOD;
if (n>m) swap(n,m);
for (LL l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
p1=n*m%MOD*(r-l+1)%MOD;
p2=(n/l)*(m/l)%MOD;
p2=p2*(cal(r)-cal(l-1)+MOD)%MOD;
p3=(m*(n/l)+n*(m/l))%MOD*ca(l,r)%MOD;
ans=(ans-(p1+p2-p3)%MOD+MOD)%MOD;
}
return printf("%lld\n",ans),0;
}