luoguP2260 [清华集训2012]模积和
题意
\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}n\%i*m\%j*[i!=j]\)
\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}n\%i*m\%j-\sum\limits_{i=1}^{min(n,m)}n\%i*m\%i\)
\(\sum\limits_{i=1}^n(n-\lfloor\frac{n}{i}\rfloor*i)\sum\limits_{j=1}^m(m-\lfloor\frac{m}{j}\rfloor*j)-\sum\limits_{i=1}^{min(n,m)}n*m-(n*\lfloor\frac{m}{i}\rfloor+m*\lfloor\frac{n}{i}\rfloor)*i+\lfloor\frac{n}{i}\rfloor*\lfloor\frac{m}{i}\rfloor*i^2\)
除法分块就好了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=19940417;
const int inv6=3323403;
const int inf=1e9;
int n,m,ans;
inline int calc1(int l,int r){return ((l+r)*(r-l+1)/2)%mod;}
inline int calc2(int x){return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;}
inline int calc(int x)
{
int res=0;
for(int l=1,r;l<=x;l=r+1)
{
r=x/(x/l);
int tmp=x*(r-l+1)%mod-(x/l)*calc1(l,r)%mod;
res=((res+tmp)%mod+mod)%mod;
}
return res;
}
signed main()
{
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);
ans=calc(n)*calc(m)%mod;
for(int l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
int tmp1,tmp2,tmp3;
tmp1=n*m%mod*(r-l+1)%mod;
tmp2=(n*(m/l)%mod+m*(n/l)%mod)%mod*calc1(l,r)%mod;
tmp3=(n/l)*(m/l)%mod*((calc2(r)-calc2(l-1))%mod+mod)%mod;
ans=((ans-tmp1+tmp2-tmp3)%mod+mod)%mod;
}
printf("%lld",ans);
return 0;
}