HDU 1796 容斥

来源:互联网 发布:google算法面试题 编辑:程序博客网 时间:2024/05/17 23:30
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn = 25;long long ans, inp[maxn];int n, m, t, len;long long gcd(long long a, long long b){return b == 0 ? a : gcd(b, a % b);}long long LCM(long long a, long long b){return a * b / gcd(a, b);}void dfs(int cur, long long lcm, int id){lcm = LCM(inp[cur], lcm);ans += (id & 1 ? 1 : -1) * (n - 1) / lcm;for (int i = cur + 1; i < len; i++)dfs(i, lcm, id + 1);}int main(int argc, char const *argv[]){while (~scanf("%d%d", &n, &m)){ans = 0; len = 0;while (m--){scanf("%d", &t);if (t > 0) inp[len++] = t;}for (int i = 0; i < len; i++)dfs(i, inp[i], 1);printf("%I64d\n", ans);}return 0;}


给定n和一个大小为m的集合,集合元素为非负整数。为1...n内能被集合里任意一个数整除的数字个数。

容斥原理的经典运用,先找出1...n内能被集合中任意一个元素整除的个数,再减去能被集合中任意两个整除的个数,即能被它们两只的最小公倍数整除的个数,因为这部分被计算了两次,然后又加上三个时候的个数,然后又减去四个时候的倍数...所以深搜,最后判断下集合元素的个数为奇还是偶,奇加偶减。

此题使用vector会迷之TLE ,未知原因。

0 0
原创粉丝点击