P2260 [清华集训2012]模积和
\[\sum_{i=1}^{n}\sum_{j=1}^{m}(n\ mod\ i)\times(m\ mod\ j)\\
=\sum_{i=1}^{n}\sum_{j=1}^{m}(n-i\lfloor\dfrac{n}{i}\rfloor)(m-j\lfloor\dfrac{m}{j}\rfloor)\\
=\sum_{i=1}^{n}(n-i\lfloor\dfrac{n}{i}\rfloor)\sum_{j=1}^{m}(m-j\lfloor\dfrac{m}{j}\rfloor)\\
=(n^2-\sum_{i=1}^{n}i\dfrac{n}{i})(m^2-\sum_{i=1}^{m}i\dfrac{m}{i})
\]
整除分块没了
写完后发现自己惊奇地过不了样例
发现原式后面还有个 \(i\not=j\) ,那就。。。
直接减去即可(\(n<m\))
\[\sum_{i=1}^{n}(n\ mod\ i)(m\ mod\ i)\\
=\sum_{i=1}^{n} (n-i\dfrac{n}{i})(m-i\dfrac{m}{i})\\
=\sum_{i=1}^{n}(nm-m*i\dfrac{n}{i}-n*i\dfrac{m}{i}+i^2\dfrac{n}{i}\dfrac{m}{i})\\
=n^2m-m\sum_{i=1}^{n}i\dfrac{n}{i}-n\sum_{i=1}^{n}i\dfrac{m}{i}+\sum_{i=1}^{n}i^2\dfrac{n}{i}\dfrac{m}{i}
\]
还是整除分块
那个二次方和需要处理 \(6\) 的逆元
写了个快速幂,照理 \(h(5)=55\) ,但是怎么都过不去。
第一时间查快速幂,还真挂了。。但是还是挂
忽然想起那个模数有没有可能不是质数
打开终端,factor 19940417
,发现是 \(7\) 的倍数 真毒瘤
线性递推逆元即可
#include<bits/stdc++.h>
typedef long long LL;
typedef double db;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f?x:-x;
}
const int mod=19940417;
int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
int n,m,ans,inv[7];
int f(int n){
int res=0;
for(int l=1,r,t;l<=n;l=r+1)
r=n/(n/l),t=1ll*(r-l+1)*(l+r)/2%mod,res=(res+1ll*t*(n/l)%mod)%mod;
return (res+mod)%mod;
}
int h(int n){
return 1ll*n*(n+1)%mod*(n+n+1)%mod*inv[6]%mod;
}
int g(int n,int m){
int res=1ll*n*m%mod*n%mod;
res=(res-1ll*m*f(n)%mod)%mod;
int tmp=0;
for(int l=1,r,t;l<=n;l=r+1)
r=std::min(n,m/(m/l)),t=1ll*(l+r)*(r-l+1)/2%mod,tmp=(tmp+1ll*t*(m/l)%mod)%mod;
res=(res-1ll*tmp*n%mod)%mod;
for(int l=1,r;l<=n;l=r+1)
r=std::min(n/(n/l),m/(m/l)),res=(res+1ll*(h(r)-h(l-1))*(n/l)%mod*(m/l)%mod)%mod;
return (res+mod)%mod;
}
signed main(){
inv[1]=1;
for(int i=2;i<=6;++i)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
n=read(),m=read();
if(n>m)std::swap(n,m);
printf("%lld\n",(1ll*(1ll*n*n%mod-f(n)+mod)*(1ll*m*m%mod-f(m)+mod)%mod-g(n,m)+mod)%mod);
}
路漫漫其修远兮,吾将上下而求索