noip模拟赛 计数
【问题描述】
给出m个数a[1],a[2],…,a[m]
求1~n中有多少数不是a[1],a[2],…,a[m]的倍数。
【输入】
输入文件名为count.in。
第一行,包含两个整数:n,m
第二行,包含m个数,表示a[1],a[2],…,a[m]
【输出】
输出文件名为count.out。
输出一行,包含1个整数,表示答案
【输入输出样例】
count.in |
count.out |
10 2 2 3 |
3 |
【数据说明】
对于60%的数据,1<=n<=106
对于另外20%的数据,m=2
对于100%的数据,1<=n<=109,0<=m<=20,1<=a[i]<=109
分析:一道比较简单的容斥原理的题.只需要dfs求出1个数的倍数有多少个,2个数的倍数有多少个......dfs暴力枚举就可以了.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; ll n, m, a[30], ans; ll gcd(ll a, ll b) { if (!b) return a; return gcd(b, a % b); } void dfs(int dep, int cnt, ll lcm) { if (dep == m + 1) { if (cnt & 1) ans += (n / lcm); else if (cnt) ans -= (n / lcm); return; } dfs(dep + 1, cnt, lcm); ll temp = lcm / gcd(lcm, a[dep]) * a[dep]; dfs(dep + 1, cnt + 1, temp); } int main() { scanf("%lld%lld", &n, &m); for (int i = 1; i <= m; i++) scanf("%lld", &a[i]); dfs(1, 0, 1); printf("%d\n", n - ans); return 0; }