1、題面函數
樣例輸入:spa
2code
5 8blog
樣例輸出:it
8io
14class
2、思路基礎
關鍵詞:線性篩im
在Zed的幫助下知道了這是一道線性篩的比較裸的題了。考試過程當中肝這道題的時間最久,費了心思找到遞推式後,發現根本不是在1s內能實現的東西。考試過程當中大三學長選擇了暴力打表打了幾十KB。。。考後向Zed請教良久知道了線性篩。線性篩最基礎的做用是篩出全部質數,時間複雜度僅爲o(n)。因爲f(x)是「積性函數」(f(a * b) = f(a) * f(b)),因此也能夠用線性篩處理。img
3、代碼
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 6 #define MAXN 200005 7 #define MAXT 25 8 9 int T, a[MAXT], n, tot, g[MAXN], p[MAXN], s[MAXN], f[MAXN], v[MAXN]; 10 11 void work() { 12 f[1] = 1, s[1] = 1; 13 for (int i = 2; i <= n; i++) { 14 if (!v[i]) p[++tot] = i, f[i] = 2; 15 for (int j = 1; j <= tot; j++) { 16 int k = i * p[j]; 17 if (k > n) break; 18 v[k] = 1; 19 if (!(i % p[j])) { 20 f[k] = g[i] ? 0 : f[i] / 2; 21 g[k] = 1; 22 break; 23 } 24 else f[k] = f[i] * 2; 25 } 26 s[i] = s[i - 1] + f[i]; 27 } 28 } 29 30 int main() { 31 scanf("%d", &T); 32 for (int i = 1; i <= T; i++) scanf("%d", &a[i]), n = max(a[i], n); 33 work(); 34 for (int i = 1; i <= T; i++) printf("%d\n", s[a[i]]); 35 return 0; 36 }