ACM-ICPC 2018 南京賽區網絡預賽 Sum
題意不復述
對數x進行質因數分解,
f(x)的求法
說人話就是如果分解質因數後:
如果有一個質因子的指數大於等於3,鴿籠原理知必然有一個含有兩個,那麼肯定無法分解成兩個square-free integer .
如果有一個質因子的指數等於2,鴿籠原理知必然有一個含有兩個,那麼沒得選,各分一個.
如果有一個質因子的指數等於1,那麼不是給就是給.
指數爲1的質因子個數是,故總方案數
f(x)性質
知道了表達式之後,就可以推導出的性質了。
約定表示質數
所以使用歐拉篩法的遍歷順序,使得每個f只會被求一次即可。
預處理所有和的前綴和
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e7+10;
const int max_prime_cnt = 1271356;
bool is_prime[maxn];
int prime[max_prime_cnt];
int prime_cnt;
int f[maxn];
ll sf[maxn];
int n;
void get_f(int n) {
memset(is_prime,1,sizeof(is_prime));
is_prime[1] = false;
f[1] = 1;
prime_cnt = 0;
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
prime[prime_cnt++] = i;
f[i] = 2;
}
int k = n/i;
for (int j = 0; j < prime_cnt && prime[j] <= k; ++j) {
is_prime[i*prime[j]] = false;
if (i%prime[j] == 0) {
int t = i/prime[j]; // t*prime[j]^2
f[i*prime[j]] = t%prime[j] ? f[t] : 0;
break;
} else {
f[i*prime[j]] = 2*f[i];
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
n = maxn-5;
get_f(n);
sf[0] = 0;
for (int i = 1; i <= n; ++i)
sf[i] = sf[i-1]+f[i];
int t;
cin >> t;
while (t--) {
cin >> n;
cout<<sf[n]<<endl;
}
return 0;
}