隐藏
「bzoj2956」模积和 - 莫比乌斯反演 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「bzoj2956」模积和 - 莫比乌斯反演

题目大意

    求:

    其中$i\neq j$。


题目分析

这道题最难的在于$i\neq j$。
我们先不考虑$i\neq j$,考虑求和。

这样就可以分块跳跃$+$等差数列求和进行计算了,和余数求和很像。

然后我们考虑如何处理$i\neq j$的问题。
我们容斥一下变成求$i=j$的模数和(保证$n\le m$)。

分别计算一下。
中间过程可能会爆$long\,long$,开__int128解决问题。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

typedef long long LL;

inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}

const LL mod=19940417;

LL n,m,ans1=0,ans2=0,ans,sum=0,tmp=0;

LL Cal1(LL x,LL y) {
return (y+x)*(y-x+1)/2%mod;
}

LL Cal2(LL x,LL y) {
return (((__int128)y*(y+1)*(2*y+1)/6%mod-(__int128)(x-1)*x*(2*x-1)/6%mod)%mod+mod)%mod;
}

int main() {
n=Get_Int();
m=Get_Int();
if(n>m)swap(n,m);
LL next;
for(LL i=1; i<=n; i=next+1) {
next=n/(n/i);
ans1=(ans1+(n/i)*Cal1(i,next)%mod)%mod;
}
for(LL i=1; i<=m; i=next+1) {
next=m/(m/i);
ans2=(ans2+(m/i)*Cal1(i,next)%mod)%mod;
}
ans=(((n*n%mod*m%mod*m%mod)+ans1*ans2%mod-ans1*m%mod*m%mod-ans2*n%mod*n%mod)%mod+mod)%mod;
for(LL i=1; i<=min(n,m); i=next+1) {
next=min(m/(m/i),n/(n/i));
tmp=(tmp+(n/i)*(m/i)%mod*Cal2(i,next)%mod)%mod;
}
for(LL i=1; i<=n; i=next+1) {
next=min(m/(m/i),n);
sum=(sum+(m/i)*Cal1(i,next)%mod)%mod;
}
sum=((n*n%mod*m%mod+tmp-ans1*m%mod-sum*n%mod)%mod+mod)%mod;
printf("%lld\n",((ans-sum)%mod+mod)%mod);
return 0;
}
姥爷们赏瓶冰阔落吧~