hdu 1286 找新朋友 (容斥原理 || 欧拉函数)
用容斥原理做的代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 7 using namespace std; 8 9 const int N = 33333; 10 11 int last[N]; 12 void pre() { 13 last[1] = 1; 14 for (int i = 2; i < N; i++) { 15 if (!last[i]) { 16 for (int j = i; j < N; j += i) { 17 last[j] = i; 18 } 19 } 20 } 21 // for (int i = 0; i < 20; i++) cout << last[i] << endl; 22 } 23 24 vector<int> fac; 25 void getFac(int n) { 26 fac.clear(); 27 while (n > 1) { 28 fac.push_back(last[n]); 29 n /= last[n]; 30 } 31 int t = (int) (unique(fac.begin(), fac.end()) - fac.begin()); 32 while (fac.size() > t) fac.pop_back(); 33 } 34 35 int cntBit(int n) { return n > 0 ? cntBit(n >> 1) + (n & 1) : 0;} 36 37 int main() { 38 pre(); 39 int T, n; 40 cin >> T; 41 while (T-- && cin >> n) { 42 getFac(n); 43 int ans = 0; 44 for (int i = 1, szi = 1 << fac.size(); i < szi; i++) { 45 int tmp = 1; 46 for (int j = 0, szj = fac.size(); j < szj; j++) { 47 if (i & 1 << j) tmp *= fac[j]; 48 } 49 if (cntBit(i) & 1) { 50 ans += n / tmp; 51 } else { 52 ans -= n / tmp; 53 } 54 } 55 cout << n - ans << endl; 56 } 57 return 0; 58 }
用欧拉函数做的代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 7 using namespace std; 8 9 const int N = 33333; 10 11 int last[N]; 12 void pre() { 13 last[1] = 1; 14 for (int i = 2; i < N; i++) { 15 if (!last[i]) { 16 for (int j = i; j < N; j += i) { 17 last[j] = i; 18 } 19 } 20 } 21 // for (int i = 0; i < 20; i++) cout << last[i] << endl; 22 } 23 24 int phi(int n) { 25 int ret = 1; 26 while (n > 1) { 27 int tmp = last[n]; 28 // cout << tmp << endl; 29 ret *= tmp - 1; 30 n /= last[n]; 31 while (tmp == last[n]) { 32 ret *= tmp; 33 n /= last[n]; 34 } 35 } 36 return ret; 37 } 38 39 int main() { 40 pre(); 41 int T, n; 42 cin >> T; 43 while (T-- && cin >> n) cout << phi(n) << endl; 44 return 0; 45 }
——written by Lyon