【zzy】yyy送禮物
阿新 • • 發佈:2018-12-18
題目連結
【分析】
- 就是求
- 與除法分塊相同,但是資料範圍更小,查詢次數更多
- 考慮遞推求解
- 設
- 則
- 不考慮 的情況,
- 當 時,對的貢獻為
- 所以
- 可以用線性篩求出
【程式碼】
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
const int N = 1e7 + 10;
int T, n;
int p[N], pr;
LL sigma[N], f[N], low[N];
void sieve(int n) {
sigma[1] = 1;
for (int i = 2; i <= n; ++i) {
if (low[i] == 0) {
low[ i] = p[++pr] = i;
sigma[i] = i + 1;
}
for (int j = 1, k = i * p[j]; j <= pr && k <= n; ++j, k = i * p[j]) {
if (i % p[j] == 0) {
low[k] = low[i] * p[j];
if (low[k] == k)
sigma[k] = (low[k] * p[j] - 1) / (p[j] - 1);
else
sigma[k] = sigma[i / low[i]] * sigma[low[i] * p[j]];
break;
} else {
low[k] = p[j];
sigma[k] = sigma[i] * sigma[p[j]];
}
}
}
for (int i = 1; i <= n; ++i)
f[i] = f[i - 1] + (i - 1) - (sigma[i] - i);
}
int main() {
sieve(10000000);
scanf("%d", &T);
for (int i = 1; i <= T; ++i) {
scanf("%d", &n);
printf("%lld\n", f[n]);
}
return 0;
}