正题
题目链接:https://www.luogu.org/problemnew/show/P2834
题目大意
求∑i=1n∑j=1m(n%i)∗(m%j)∗(i!=j)\sum_{i=1}^n\sum_{j=1}^m(n\%i)*(m\%j)*(i!=j)i=1∑nj=1∑m(n%i)∗(m%j)∗(i!=j)
解题思路
∑i=1n(n%i)∗∑j=1m(m%j)−∑i=1min{n,m}(n%i)∗(m%i)\sum_{i=1}^n(n\%i)*\sum_{j=1}^m(m\%j)-\sum_{i=1}^{min\{n,m\}}(n\%i)*(m\%i)i=1∑n(n%i)∗j=1∑m(m%j)−i=1∑min{n,m}(n%i)∗(m%i)
前面的很好求,我们考虑如何求后面的。
单独考虑∑i=1n(n%i)=n2−∑i=1n⌊n/i⌋∗i\sum_{i=1}^{n}(n\%i)=n^2-\sum_{i=1}^n\lfloor n/i\rfloor*ii=1∑n(n%i)=n2−i=1∑n⌊n/i⌋∗i
同理∑i=1min{n,m}(n−⌊n/i⌋∗i)∗(m−⌊m/i⌋∗i)\sum_{i=1}^{min\{n,m\}}(n-\lfloor n/i\rfloor*i)*(m-\lfloor m/i\rfloor*i)i=1∑min{n,m}(n−⌊n/i⌋∗i)∗(m−⌊m/i⌋∗i)
∑i=1min{n,m}n∗m−(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i+⌊m/i⌋∗⌊n/i⌋∗i2\sum_{i=1}^{min\{n,m\}}n*m-(m*\lfloor n/i\rfloor+n*\lfloor m/i\rfloor)*i+\lfloor m/i\rfloor*\lfloor n/i\rfloor*i^2i=1∑min{n,m}n∗m−(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i+⌊m/i⌋∗⌊n/i⌋∗i2
n∗m∗min{n,m}−∑i=1min{n,m}(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i−⌊m/i⌋∗⌊n/i⌋∗i2n*m*min\{n,m\}-\sum_{i=1}^{min\{n,m\}}(m*\lfloor n/i\rfloor+n*\lfloor m/i\rfloor)*i-\lfloor m/i\rfloor*\lfloor n/i\rfloor*i^2n∗m∗min{n,m}−i=1∑min{n,m}(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i−⌊m/i⌋∗⌊n/i⌋∗i2
然后除了i2i^2i2其他用整体分块都好求,之后我们考虑如何求∑i=1min{n,m}i2\sum_{i=1}^{min\{n,m\}} i^2∑i=1min{n,m}i2
∑i=1min{n,m}i2=i∗(i+1)∗(2∗i+1)6\sum_{i=1}^{min\{n,m\}} i^2=\frac{i*(i+1)*(2*i+1)}{6}i=1∑min{n,m}i2=6i∗(i+1)∗(2∗i+1)
数学归纳法
∑i=1min{n,m}x2=x∗(x+1)∗(2∗x+1)6\sum_{i=1}^{min\{n,m\}} x^2=\frac{x*(x+1)*(2*x+1)}{6}i=1∑min{n,m}x2=6x∗(x+1)∗(2∗x+1)
(∑i=1min{n,m}x2)+(x+1)2=x∗(x+1)∗(2∗x+1)6+(x+1)2(\sum_{i=1}^{min\{n,m\}} x^2)+(x+1)^2=\frac{x*(x+1)*(2*x+1)}{6}+(x+1)^2(i=1∑min{n,m}x2)+(x+1)2=6x∗(x+1)∗(2∗x+1)+(x+1)2
=>(x+1)∗(2∗x2+x)+6(x+1)26=>\frac{(x+1)*(2*x^2+x)+6(x+1)^2}{6}=>6(x+1)∗(2∗x2+x)+6(x+1)2
=>(x+1)∗(2∗x2+7x+6)6=>\frac{(x+1)*(2*x^2+7x+6)}{6}=>6(x+1)∗(2∗x2+7x+6)
=>(x+1)∗(x+2)∗(2∗x+3)6=>\frac{(x+1)*(x+2)*(2*x+3)}{6}=>6(x+1)∗(x+2)∗(2∗x+3)
=>(x+1)∗(x+2)∗(2∗(x+1)+1)6=>\frac{(x+1)*(x+2)*(2*(x+1)+1)}{6}=>6(x+1)∗(x+2)∗(2∗(x+1)+1)
证毕
codecodecode
#include<cstdio>
#include<algorithm>
#define ll long long
#define sum(l,r) ((l+r)*(r-l+1)/2)
using namespace std;
const int XJQ=1e9+7;
ll n,m,ans;
ll Qs(ll n,ll k)
{ll ans=0;for(ll x=1,gx;x<=min(n,k);x=gx+1){gx=min(k/(k/x),n);(ans+=(k/x)*sum(x,gx)%XJQ)%=XJQ;}return ans%XJQ;
}
ll lx(ll x)
{return x*(x+1)%XJQ*(2*x+1)%XJQ*166666668%XJQ;
}
int main()
{scanf("%lld%lld",&n,&m);if(m>n) swap(n,m);ans=(n*n-Qs(n,n))%XJQ;ans=(m*m-Qs(m,m))%XJQ*ans%XJQ;ans=(ans+Qs(m,m)*n%XJQ)%XJQ;ans=(ans+Qs(m,n)*m%XJQ)%XJQ;ans=(ans-m*m%XJQ*n%XJQ+XJQ)%XJQ;int tmp=0;for(ll i=1,dn,dm,next;i<=m;i=next+1){dm=m/i;dn=n/i;next=min(n/dn,m/dm);(tmp+=(lx(next)-lx(i-1))*dn%XJQ*dm%XJQ)%=XJQ;}printf("%lld",(ans-tmp+XJQ)%XJQ);
}