【UVa#10325】The Lottery

青旅半醒 2023-06-05 08:54 107阅读 0赞

Description

UVa#10325

给定n和m个数,求1~n中不被这m个数中任意一个数整除的数的个数

Solution

容斥原理

假设现在求1~n中被这a,b中任意一个数整除的数的个数

这个区间中能被a整除的数的个数是$\lfloor\frac{n}{a}\rfloor$

同理,能被b整除的数的个数是$\lfloor\frac{n}{b}\rfloor$

那么被a,b两个数中任意一个数整除的数有$\lfloor\frac{n}{a}\rfloor+\lfloor\frac{n}{b}\rfloor-\lfloor\frac{n}{lcm(a,b)}\rfloor$

这是因为a,b的公倍数会被多算一次,a,b的公倍数一共有$\lfloor\frac{n}{lcm(a,b)}\rfloor$个

推广到m个数上

被这m个数中的任意一个数整数的数的个数就是

被任意一个数整除的个数-被任意两个数的公倍数整除的个数+被任意三个数的公倍数整除的数的个数-……

那么我们枚举一下,然后利用容斥原理就可以了

最后用总数减去结果就是答案了

时间复杂度$O(2^{m}\times m)$

Code

  1. #include <bits/stdc++.h>
  2. namespace shl {
  3. typedef long long ll;
  4. int a[20];
  5. int n, m;
  6. ll ans;
  7. ll gcd(ll a, ll b) {
  8. if (!b) return a;
  9. return gcd(b, a % b);
  10. }
  11. ll lcm(ll a, ll b) {
  12. return a / gcd(a, b) * b;
  13. }
  14. int main() {
  15. while (~scanf("%d%d", &n, &m)) {
  16. memset(a, 0, sizeof(a));
  17. ans = n;
  18. int num;
  19. for (register int i = 1; i <= m; ++i)
  20. scanf("%d", &a[i]);
  21. int full = 1 << m;
  22. for (register int i = 1; i < full; ++i) {
  23. num = 0;
  24. ll sum = 1ll;
  25. for (register int j = 0; j < m; ++j)
  26. if (i & (1 << j)) {
  27. num++;
  28. sum = lcm(sum, a[j + 1]);
  29. }
  30. if (num & 1) ans -= n / sum;
  31. else ans += n / sum;
  32. }
  33. printf("%lld\n", ans);
  34. }
  35. return 0;
  36. }
  37. };
  38. int main() {
  39. shl :: main();
  40. return 0;
  41. }

$\lfloor\frac{n}{a}\rfloor$

转载于:https://www.cnblogs.com/shl-blog/p/11382695.html

发表评论

表情:
评论列表 (有 0 条评论,107人围观)

还没有评论,来说两句吧...

相关阅读

    相关 UVA11752 The Super Powers

    最近几天的状态着实不好,数电设计的答辩不能更逗,万幸是终于到家了,看到群里有各种群赛十分开心,希望能找回刷题的动力,调整下状态。 这道题是很久前做的,细节记不太清了。。。

    相关 uva 1623——Enter The Dragon

    题意:有n个装满水的湖,可以预知将来m天下雨情况,每次下满一个湖,或者不下,不下雨的时候可以让某个湖变干,问是否存在一种方案使得每次下雨之前湖总是干的。 思路:贪心

    相关 UVA 12099 The Bookcase(dp)

    题意: 有N本书,第i本书有一个高度Hi和宽度Wi,现要求构建一个三层的书架,你必须把所有书放在书架上。设三层高度(该层最高的书的高度)之和为h,书架总宽度(即每层总宽度