題目大意:
分析:
設
那麼
爲偶否則
那麼發現就是小於的最大平方數的根號
那麼
枚舉考慮有多少個,
那麼
這就很像一個入門的莫比烏斯函數題完全平方數,
的無平方因子數是
然後就可以將後面的式子換一下,
設,
換成枚舉
有一個性質就是
所以
預處理
那麼對於每次的我們就可以在的時間內得出ans
當然也可以對進行整除分塊
代碼:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define N 10000005
using namespace std;
typedef long long ll;
int pri[N], phi[N], T, cnt;
bool vis[N];
ll n, ans;
void Pre_Work() {
phi[1] = 1;
rep(i, 2, N - 5) {
if (!vis[i]) pri[++cnt] = i, phi[i] = i - 1;
for (int j = 1; j <= cnt; j++) {
if (i * pri[j] > N - 5) break;
vis[i * pri[j]] = 1;
if (i % pri[j] != 0) { phi[i * pri[j]] = (ll)phi[i] * (pri[j] - 1); }
if (i % pri[j] == 0) { phi[i * pri[j]] = (ll)phi[i] * pri[j]; break; }
}
}
}
int main() {
Pre_Work();
scanf("%d", &T);
while (T--) {
scanf("%lld", &n);
ans = 0;
for (ll i = 1; i * i <= n; i++) ans = ans + 1ll * (n / (i * i)) * phi[i];
printf("%lld\n", ans);
}
return 0;
}