版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/89577678
正题
题目链接:https://www.luogu.org/problemnew/show/P2834
题目大意
求
i=1∑nj=1∑m(n%i)∗(m%j)∗(i!=j)
解题思路
i=1∑n(n%i)∗j=1∑m(m%j)−i=1∑min{n,m}(n%i)∗(m%i)
前面的很好求,我们考虑如何求后面的。
单独考虑
i=1∑n(n%i)=n2−i=1∑n⌊n/i⌋∗i
同理
i=1∑min{n,m}(n−⌊n/i⌋∗i)∗(m−⌊m/i⌋∗i)
i=1∑min{n,m}n∗m−(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i+⌊m/i⌋∗⌊n/i⌋∗i2
n∗m∗min{n,m}−i=1∑min{n,m}(m∗⌊n/i⌋+n∗⌊m/i⌋)∗i−⌊m/i⌋∗⌊n/i⌋∗i2
然后除了
i2其他用整体分块都好求,之后我们考虑如何求
∑i=1min{n,m}i2
i=1∑min{n,m}i2=6i∗(i+1)∗(2∗i+1)
数学归纳法
i=1∑min{n,m}x2=6x∗(x+1)∗(2∗x+1)
(i=1∑min{n,m}x2)+(x+1)2=6x∗(x+1)∗(2∗x+1)+(x+1)2
=>6(x+1)∗(2∗x2+x)+6(x+1)2
=>6(x+1)∗(2∗x2+7x+6)
=>6(x+1)∗(x+2)∗(2∗x+3)
=>6(x+1)∗(x+2)∗(2∗(x+1)+1)
证毕
code
#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);
}