平凡的函式(素數篩)
阿新 • • 發佈:2020-09-04
題目描述
某一天,你發現了一個神奇的函式\(f(x)\),它滿足很多神奇的性質:
- \(f(1) = 1\)
- \(f(p^c)=p \bigoplus c\)(\(p\)為質數,\(\bigoplus\) 為異或)
- \(f(ab) = f(a) * f(b)\)(a,b互質)
輸入
給定\(n\)
輸出
求出\(\sum_{i=1}^{n} f(i)\)
樣例輸入
23333
樣例輸出
171806766
solution
線性篩,然後對數質因數分解
剩下的就暴力乘法更新\(f\)陣列
code
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; inline int read(){ int x = 0, w = 1; char ch = getchar(); for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return x * w; } const int ss = 50000010; int f[ss], prime[ss]; bool vis[ss]; int cnt; signed main(){ freopen("func.in", "r", stdin); freopen("func.out", "w", stdout); unsigned long long ans = 1; f[1] = 1; register int n = read(); for(register int i = 2; i <= n; i++){ if(!vis[i]) prime[++cnt] = i, f[i] = i ^ 1; for(register int j = 1; i * prime[j] <= n; j++){ vis[i * prime[j]] = 1; if(i % prime[j] == 0){ register int tmp = i, c = 1; while(tmp % prime[j] == 0) tmp /= prime[j], ++c; f[i * prime[j]] = f[tmp] * (prime[j] ^ c); break; } f[i * prime[j]] = f[i] * f[prime[j]]; } ans += f[i]; } cout << ans << endl; return 0; }