版权声明:写得不好,随便转载,但请注明出处,感激不尽 https://blog.csdn.net/xyc1719/article/details/83447241
【一句话题意】求函数
fht(n,m)=Σi=1nΣj=1m(nmodi)∗(mmodj)的值。
n,m<=1e9
【分析】首先拆开求和式子得到
Σi=1nΣj=1m(nmodi)∗(mmodj)==Σi=1n(nmodi)∗Σj=1m(mmodj)
这样就可以化
O(nm)算法为
O(n+m)算法。但是n和m大于1e8,所以优化的程度不够,这个时候就需要优秀的数学变换。证明如下。
Σi=1n(nmodi)
=Σi=1n(n−⌊in⌋∗i)
=Σi=1nn−Σi=1ni∗Σi=1n⌊in⌋
=n2−n∗i∗Σi=1n⌊in⌋
一个明显的可以整除分块的式子,对于
⌊in⌋其实只有
2n
种情况。在i小于
n
时
⌊in⌋的值其实是不连续的,共有
n
种情况。当i大于
n
时,
⌊in⌋的值一定连续且只有
n
种情况。
【code】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll P=1e9+7;
ll n,m;
inline ll calc(ll x){
ll j,s,ans=x*x;
for (ll i=1;i<=x;i++){
j=x/(x/i);
ans=ans-(i+j)*(j-i+1)/2*(x/i);
i=j;
}
return ans%P;
}
int main(){
scanf("%lld%lld",&n,&m);
cout<<calc(n)%P*calc(m)%P<<endl;
return 0;
}