[关闭]
@ZCDHJ 2019-08-10T00:08:06.000000Z 字数 1581 阅读 764

同余类最短路 笔记

未分类


给定 的取值范围,求使得 元一次方程 有非负整数解的 的个数。

很明显如果 ,则 加上任意一个 也能使得方程有非负整数解。转化为如 使方程有非负整数解则 也可以。那么对于任意一个 的剩余系来讨论,设 满足 可以使得方程有非负整数解且 最小,那么就可以看成是一个最短路模型,求出所有的 ,如果 就满足条件。为了使速度最快选择最小的 ,将答案转化为前缀和相减的形式计算即可。为什么这样算出的答案不重不漏呢?因为这里的每个 必然只能构造出 的系数为 的解,然后再用这个数统计 的系数不为 的解,所以不重不漏。

这里放上模板题 Luogu2371 墨墨的等式 的代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. typedef long long LL;
  6. #define int long long
  7. const int MAXN = 20;
  8. const int MAXA = 5e5;
  9. int n, m, b_max, b_min;
  10. int a[MAXN | 1], fst[MAXN | 1], dist[MAXA];
  11. struct Queue {
  12. int dis, x;
  13. Queue() : dis(0), x(0) {}
  14. Queue(int a, int b) : x(a), dis(b) {}
  15. friend bool operator< (const Queue &lhs, const Queue &rhs) {
  16. return lhs.dis > rhs.dis;
  17. }
  18. };
  19. inline int read() {
  20. register int x = 0;
  21. register char ch = getchar();
  22. while (!isdigit(ch)) ch = getchar();
  23. while (isdigit(ch)) {
  24. x = x * 10 + ch - '0';
  25. ch = getchar();
  26. }
  27. return x;
  28. }
  29. void Dijkstra() {
  30. memset(dist, 0x3f, sizeof(dist));
  31. dist[0] = 0;
  32. std::priority_queue < Queue > q;
  33. q.push(Queue(0, 0));
  34. do {
  35. Queue from = q.top();
  36. q.pop();
  37. if (dist[from.x] != from.dis) continue;
  38. for (int i = 1; i <= n; ++i) {
  39. int to = (from.x + a[i]) % m, w = a[i];
  40. if (dist[to] > dist[from.x] + w) {
  41. dist[to] = dist[from.x] + w;
  42. q.push(Queue(to, dist[to]));
  43. }
  44. }
  45. } while (!q.empty());
  46. }
  47. LL query(LL x) {
  48. LL res = 0;
  49. for (int i = 0; i < m; ++i)
  50. if (dist[i] <= x)
  51. res += (x - dist[i]) / m + 1;
  52. return res;
  53. }
  54. signed main() {
  55. freopen("code.in", "r", stdin);
  56. freopen("code.out", "w", stdout);
  57. n = read();
  58. scanf("%lld %lld", &b_min, &b_max);
  59. m = 1e9;
  60. for (int i = 1; i <= n; ++i) a[i] = read(), m = std::min(m, a[i]);
  61. Dijkstra();
  62. printf("%lld\n", query(b_max) - query(b_min - 1));
  63. return 0;
  64. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注