美味果冻
∑i=1n∑j=1ii×⌊ij⌋j∑i=1n∑j=inj×⌊ji⌋i\sum_{i = 1} ^{n} \sum_{j = 1} ^{i} i \times \lfloor \frac{i}{j} \rfloor ^ j\\ \sum_{i = 1} ^{n} \sum_{j = i} ^{n} j \times \lfloor \frac{j}{i} \rfloor ^ i\\ i=1∑nj=1∑ii×⌊ji⌋ji=1∑nj=i∑nj×⌊ij⌋i
接下来只需要从小到大枚举iii,因为有j∈[ki,(k+1)i],⌊ji⌋=kj \in[ki, (k + 1)i], \lfloor \frac{j}{i} \rfloor = kj∈[ki,(k+1)i],⌊ij⌋=k,所以这里有一个分块性质,差分前缀和即可得到。
最后在得到的数组中乘上一个数组下标,在求一次前缀和即是答案了。
#include <bits/stdc++.h>using namespace std;const int N = 3e6 + 10, mod = 1e9 + 7;int f[N], g[N], n;void init() {for (int i = 1; i < N; i++) {g[i] = 1;}for (int i = 1; i < N; i++) {for (int j = i; j < N; j += i) {int l = j, r = j + i;g[j / i] = 1ll * g[j / i] * (j / i) % mod;int cur = g[j / i];f[l] = (f[l] + cur) % mod;if (r < N) f[r] = (f[r] - cur + mod) % mod;}}for (int i = 1; i < N; i++) {f[i] = (f[i - 1] + f[i]) % mod;}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);init();scanf("%d", &n);int ans = 0;for (int i = 1; i <= n; i++) {ans = (ans + 1ll * i * f[i] % mod) % mod;}printf("%d\n", ans);return 0;
}