题意:F(n) = (n % 1) + (n % 2) + (n % 3) + … (n % n)。其中%表示Mod,也就是余数。
例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3。
给出n,计算F(n), 由于结果很大,输出Mod 1000000007的结果即可。
输入:输入1个数N(2 <= N <= 10^12)。
输出:输出F(n) Mod 1000000007的结果。
题解:
F
(
n
)
=
∑
1
n
n
%
i
F(n)=\sum_{1}^{n}n\%i
F(n)=∑1nn%i 等价于
F
(
n
)
=
∑
1
n
n
−
⌊
n
i
⌋
∗
i
F(n)=\sum_{1}^{n}n-\lfloor\frac{n}{i}\rfloor*i
F(n)=∑1nn−⌊in⌋∗i
因此,
F
(
n
)
=
n
2
−
∑
1
n
⌊
n
i
⌋
∗
i
F(n)=n^2-\sum_{1}^{n}\lfloor\frac{n}{i}\rfloor*i
F(n)=n2−∑1n⌊in⌋∗i
前一部分可以直接算出,后一部分可以用分块的做法算出,时间复杂度为
O
(
n
)
O(\sqrt{n})
O(n)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define mes(a, val) memset(a, val, sizeof a)
#define mec(b, a) memcpy(b, a, sizeof a)
const ll mod = 1000000007;
ll inv2;
ll ksm(ll a, ll n, ll mod)
{
ll res = 1ll;
while(n){
if(n & 1) res = res * a % mod;
a = a * a % mod;
n >>= 1;
}
return res;
}
ll MOD(ll n){
return ((n % mod) + mod) % mod;
}
ll getsum(ll l, ll r){
ll ans = MOD(MOD(r - l + 1) * MOD(l + r));
ans = MOD(ans * inv2);
return ans;
}
ll solve(ll n){
ll ans = 0;
for(ll l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += MOD((n / l) * getsum(l, r));
ans = MOD(ans);
}
return MOD(ans);
}
int main()
{
inv2 = ksm(2ll, mod - 2, mod);
ll n; scanf("%lld", &n);
ll ans = MOD(MOD(n) * MOD(n));
ll tmp = solve(n);
ans = MOD(ans - solve(n));
printf("%lld\n", ans);
return 0;
}