hdu 1796 How many integers can you find

题意:

      求1->n-1之间能被一个集合A内元素整除的数的个数,例如n = 12, A = {2, 3} 则能被A集合元素整除的数的集合为{2,  3, 4 , 6, 8, 9, 10}则结果为7。

解法:容斥定理,用回溯算法。

hdu 1796 How many integers can you find_第1张图片

/* Author: ACb0y Date: 2010-9-10 Type: 容斥 + DFS ProblemId: hdu 1796 How many integers can you find Result: 2941088 2010-09-10 18:25:14 Accepted 1796 1515MS 276K 1312 B C++ ACb0y */ #include <iostream> using namespace std; #define llint __int64 int cnt; int n, m; int vis[12]; int t[12]; int d[12]; //欧几里得求最大公约数 llint gcd(llint a, llint b) { if (a % b == 0) { return b; } else { return gcd(b, a % b); } } //用回溯求容斥 void dfs(int num, int pos, llint &sum) { int i; if (pos == num) { llint lcm = 1; for (i = 0; i < num; i++) { lcm = lcm * t[i] / gcd(lcm, t[i]); } //奇数是加 if (num & 1) { sum += (n - 1) / lcm; //偶数是减 } else { sum -= (n - 1) / lcm; } } else { for (i = pos; i < cnt; i++) if (pos == 0 || (!vis[i] && d[i] > t[pos - 1])) { vis[i] = 1; t[pos] = d[i]; dfs(num, pos + 1, sum); vis[i] = 0; } } } int main() { #ifndef ONLINE_JUDGE freopen("1796.txt", "r", stdin); #endif while (cin >> n >> m) { int i, j; cnt = 0; for (i = 0; i < m; i++) { int temp; cin >> temp; if (temp != 0) { d[cnt++] = temp; } } llint ans = 0; for (i = 1; i <= cnt; i++) { memset(vis, 0, sizeof(vis)); dfs(i, 0, ans); } cout << ans << endl; } return 0; }   

 

你可能感兴趣的:(c,算法,2010)