[关闭]
@qq290637843 2021-04-15T11:48:32.000000Z 字数 29287 阅读 425

2019西安

题目见https://ac.nowcoder.com/acm/contest/3732

A、City

简单题

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul n, m;
  7. ull ans = 0;
  8. int main()
  9. {
  10. std::scanf("%u%u", &n, &m);
  11. for (ul x = 0; x <= n; ++x) {
  12. for (ul y = 0; y <= m; ++y) {
  13. ans += ull(std::min(x, n - x) * 2 + 1) * ull(std::min(y, m - y) * 2 + 1) - 1 >> 1;
  14. }
  15. }
  16. std::printf("%llu\n", ans);
  17. return 0;
  18. }

B、Black and White

注意本题不同于常规之处,轴向上,轴向右。
首先在图上画上的直线,于是可以分批处理每一步的贡献。为了方便起见,作出如下调整:当时,将问题变为:后步左侧的白减黑,减掉,前步右侧的黑减白,再两倍;当时,将问题变为:前步左侧的白减黑,减掉,后步右侧的黑减白,再两倍(下文将会把新目标值记为)。于是两个问题分别变为:当时,偶标向上步数减去奇标向上步数;当时,奇标向右步数减去偶标向右步数。
现在将正权标的数量记为,符权标的数量记为时,偶标为正权标,奇标为负权标;时,奇标为正权标,偶标为负权标)。于是:
时,答案为:
时,答案为:
(注意,上述两算式,只要任何地方非法都为零)。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul mod = 998244353;
  7. ul mul(ul a, ul b)
  8. {
  9. return ull(a) * ull(b) % mod;
  10. }
  11. void exgcd(li a, li b, li& x, li& y)
  12. {
  13. if (b) {
  14. exgcd(b, a % b, y, x);
  15. y -= a / b * x;
  16. } else {
  17. x = 1;
  18. y = 0;
  19. }
  20. }
  21. ul inverse(ul a)
  22. {
  23. li x, y;
  24. exgcd(a, mod, x, y);
  25. return x < 0 ? x + li(mod) : x;
  26. }
  27. const ul maxsz = 2e5;
  28. ul fac[maxsz + 1];
  29. ul fiv[maxsz + 1];
  30. ul T;
  31. li n, m, k;
  32. ul binomial(li a, li b)
  33. {
  34. return (b >= 0 && b <= a) ? mul(fac[a], mul(fiv[a - b], fiv[b])) : ul(0);
  35. }
  36. int main()
  37. {
  38. fac[0] = 1;
  39. for (ul i = 1; i <= maxsz; ++i) {
  40. fac[i] = mul(fac[i - 1], i);
  41. }
  42. fiv[maxsz] = inverse(fac[maxsz]);
  43. for (ul i = maxsz; i >= 1; --i) {
  44. fiv[i - 1] = mul(fiv[i], i);
  45. }
  46. std::scanf("%u", &T);
  47. for (ul Case = 1; Case <= T; ++Case) {
  48. std::scanf("%d%d%d", &n, &m, &k);
  49. k += k;
  50. li ans;
  51. if (n <= m) {
  52. if (n & 1) {
  53. --k;
  54. }
  55. li p = (n + m) / 2;
  56. li q = (n + m + 1) / 2;
  57. if ((n ^ k) & 1) {
  58. ans = 0;
  59. } else {
  60. ans = mul(binomial(p, (n + k) / 2), binomial(q, (n - k) / 2));
  61. }
  62. } else {
  63. if (m & 1) {
  64. if (n & 1) {
  65. --k;
  66. } else {
  67. ++k;
  68. }
  69. }
  70. li p = (n + m + 1) / 2;
  71. li q = (n + m) / 2;
  72. if ((m ^ k) & 1) {
  73. ans = 0;
  74. } else {
  75. ans = mul(binomial(p, (m + k) / 2), binomial(q, (m - k) / 2));
  76. }
  77. }
  78. std::printf("%u\n", ans);
  79. }
  80. return 0;
  81. }

C、Dirichlet k -th root

首先注意到,如果有一函数满足,比如质因数个数函数即可,那么将可以定义的导函数为,这样定义的导函数满足以下规则

于是等价于,即,于是

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul mod = 998244353;
  7. ul plus(ul a, ul b)
  8. {
  9. return a + b < mod ? a + b : a + b - mod;
  10. }
  11. ul minus(ul a, ul b)
  12. {
  13. return a < b ? a + mod - b : a - b;
  14. }
  15. ul mul(ul a, ul b)
  16. {
  17. return ull(a) * ull(b) % mod;
  18. }
  19. void exgcd(li a, li b, li& x, li& y)
  20. {
  21. if (b) {
  22. exgcd(b, a % b, y, x);
  23. y -= a / b * x;
  24. } else {
  25. x = 1;
  26. y = 0;
  27. }
  28. }
  29. ul inverse(ul a)
  30. {
  31. li x, y;
  32. exgcd(a, mod, x, y);
  33. return x < 0 ? x + li(mod) : x;
  34. }
  35. const ul maxn = 1e5;
  36. ul g[maxn + 1];
  37. ul f[maxn + 1];
  38. class node {
  39. public:
  40. ul next = 0;
  41. ul val = 0;
  42. };
  43. ul n, k;
  44. ul tot = 0;
  45. node nodes[1066751];
  46. ul head[maxn + 1];
  47. ul ln[maxn + 1];
  48. std::vector<bool> notprime(maxn + 1, false);
  49. std::vector<ul> primes;
  50. int main()
  51. {
  52. std::scanf("%u%u", &n, &k);
  53. for (ul i = 2; i <= n; ++i) {
  54. if (!notprime[i]) {
  55. primes.push_back(i);
  56. ln[i] = 1;
  57. }
  58. for (ul p : primes) {
  59. if (i * p > n) {
  60. break;
  61. }
  62. notprime[i * p] = true;
  63. ln[i * p] = ln[i] + 1;
  64. if (i % p == 0) {
  65. break;
  66. }
  67. }
  68. }
  69. for (ul i = 1; i <= n; ++i) {
  70. for (ul j = i + i; j <= n; j += i) {
  71. ++tot;
  72. nodes[tot].val = i;
  73. nodes[tot].next = head[j];
  74. head[j] = tot;
  75. }
  76. }
  77. ul kinv = inverse(k);
  78. for (ul i = 1; i <= n; ++i) {
  79. std::scanf("%u", &g[i]);
  80. }
  81. f[1] = 1;
  82. for (ul x = 2; x <= n; ++x) {
  83. for (ul it = head[x]; it; it = nodes[it].next) {
  84. ul d = nodes[it].val;
  85. f[x] = plus(f[x], minus(mul(f[d], mul(g[x / d], ln[x / d])), mul(k, mul(mul(f[d], ln[d]), g[x / d]))));
  86. }
  87. f[x] = mul(mul(f[x], kinv), inverse(ln[x]));
  88. }
  89. for (ul i = 1; i <= n; ++i) {
  90. if (i != 1) {
  91. std::putchar(' ');
  92. }
  93. std::printf("%u", f[i]);
  94. }
  95. std::putchar('\n');
  96. return 0;
  97. }

D、Fire

表示从节点出发完成任务并回到且还能离开,最晚第几天中午必须到表示从节点出发完成任务留在的子树中某个叶子上,最晚第几天中午必须到
于是只考虑该怎么转移,下文中下标不再表示节点编号,而是表示“当前节点的第几个子节点”,且子节点已经依据从小到大排序。


预处理以及以及即可。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using llf = long double;
  7. const ul maxn = 1e5;
  8. std::vector<ul> edges[maxn + 1];
  9. ll k;
  10. ll a[maxn + 1];
  11. ul n;
  12. ll f[maxn + 1];
  13. ll g[maxn + 1];
  14. ll sz[maxn + 1];
  15. ll sum[maxn + 1];
  16. ll premin[maxn + 1];
  17. ll sufmin[maxn + 1];
  18. void search(ul curr, ul prev)
  19. {
  20. sz[curr] = 1;
  21. if (edges[curr].size() == 1) {
  22. f[curr] = std::min(a[curr], a[curr] + k - 2);
  23. g[curr] = a[curr];
  24. return;
  25. }
  26. for (ul next : edges[curr]) {
  27. if (next == prev) {
  28. continue;
  29. }
  30. search(next, curr);
  31. sz[curr] += sz[next];
  32. }
  33. std::sort(edges[curr].begin(), edges[curr].end(), [&](ul a, ul b){return (a == prev) != (b == prev) ? a == prev : f[a] + sz[a] + sz[a] - 1 < f[b] + sz[b] + sz[b] - 1;});
  34. sum[0] = 0;
  35. premin[0] = 1e18;
  36. for (ul i = 1; i != edges[curr].size(); ++i) {
  37. ul t = edges[curr][i];
  38. sum[i] = sum[i - 1] + sz[t] + sz[t];
  39. premin[i] = std::min(premin[i - 1], f[t] - sum[i - 1]);
  40. }
  41. sufmin[edges[curr].size()] = 1e18;
  42. for (ul i = edges[curr].size() - 1; i; --i) {
  43. ul t = edges[curr][i];
  44. sufmin[i] = std::min(sufmin[i + 1], f[t] - sum[i - 1]);
  45. }
  46. f[curr] = std::min(std::min(a[curr], premin[edges[curr].size() - 1] - 1), a[curr] + k - sum[edges[curr].size() - 1] - 2);
  47. g[curr] = -1e18;
  48. for (ul b = 1; b != edges[curr].size(); ++b) {
  49. ul t = edges[curr][b];
  50. ll tmp = std::min(std::min(std::min(std::min(a[curr], premin[b - 1] - 1), sufmin[b + 1] - 1 + sz[t] + sz[t]), g[t] - 1 - sum[edges[curr].size() - 1] + sz[t] + sz[t]), a[curr] + k - sum[edges[curr].size() - 1] + sz[t] + sz[t] - 2);
  51. g[curr] = std::max(g[curr], tmp);
  52. }
  53. }
  54. int main()
  55. {
  56. std::scanf("%u%lld", &n, &k);
  57. for (ul i = 1; i <= n - 1; ++i) {
  58. ul x, y;
  59. std::scanf("%u%u", &x, &y);
  60. edges[x].push_back(y);
  61. edges[y].push_back(x);
  62. }
  63. edges[1].push_back(0);
  64. for (ul i = 1; i <= n; ++i) {
  65. std::scanf("%lld", &a[i]);
  66. }
  67. search(1, 0);
  68. std::printf("%lld\n", g[1] < 0 ? ll(-1) : g[1]);
  69. return 0;
  70. }

E、Flow

简单题

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul maxn = 1e5;
  7. class edge_t {
  8. public:
  9. ul to;
  10. ul val;
  11. edge_t()=default;
  12. edge_t(ul a, ul b): to(a), val(b) {}
  13. };
  14. std::vector<edge_t> edges[maxn + 1];
  15. ull sum = 0;
  16. std::vector<ul> tmp;
  17. ull s[maxn + 1];
  18. ul n, m;
  19. int main()
  20. {
  21. std::scanf("%u%u", &n, &m);
  22. for (ul i = 1; i <= m; ++i) {
  23. ul x, y, z;
  24. std::scanf("%u%u%u", &x, &y, &z);
  25. edges[x].push_back(edge_t(y, z));
  26. edges[y].push_back(edge_t(x, z));
  27. sum += z;
  28. }
  29. sum /= m / edges[1].size();
  30. for (auto e : edges[1]) {
  31. tmp.resize(0);
  32. for (ul prev = 1, curr = e.to; ; e = edges[e.to][0].to == prev ? edges[e.to][1] : edges[e.to][0], prev = curr, curr = e.to) {
  33. tmp.push_back(e.val);
  34. if (e.to == n) {
  35. break;
  36. }
  37. }
  38. std::sort(tmp.begin(), tmp.end());
  39. for (ul i = 0; i != tmp.size(); ++i) {
  40. s[i] += tmp[i] - (i ? tmp[i - 1] : ul(0));
  41. }
  42. }
  43. ull ans = 0;
  44. for (ul i = 0; i != tmp.size(); ++i) {
  45. ull able = std::min(sum, s[i]);
  46. sum -= able;
  47. ans += able * i;
  48. }
  49. std::printf("%llu\n", ans);
  50. return 0;
  51. }

F、Game

爬山

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. li check(ul a, ul b)
  7. {
  8. if (a == b || a == 30 || b == 30) {
  9. return 0;
  10. } else if (a == 31 && b == 32) {
  11. return -1;
  12. } else if (a == 32 && b == 31) {
  13. return 1;
  14. } else if (a == 31) {
  15. return 1;
  16. } else if (b == 31) {
  17. return -1;
  18. } else if (a > b) {
  19. return 1;
  20. } else {
  21. return -1;
  22. }
  23. }
  24. li check(ul a[], ul b[])
  25. {
  26. for (ul ai = 1, bi = 1; ; ) {
  27. if (ai == 25 || bi == 25) {
  28. return bi - ai;
  29. }
  30. li tmp = check(a[ai], b[bi]);
  31. if (tmp >= 0) {
  32. ++bi;
  33. }
  34. if (tmp <= 0) {
  35. ++ai;
  36. }
  37. }
  38. return 0;
  39. }
  40. ul check2(ul a[], ul b[])
  41. {
  42. ul ret = 0;
  43. if (check(a, b) >= 0) {
  44. ++ret;
  45. }
  46. for (ul i = 1; i + 1 <= 24; ++i) {
  47. for (ul j = i + 1; j <= 24; ++j) {
  48. if (b[i] == b[j]) {
  49. continue;
  50. }
  51. std::swap(b[i], b[j]);
  52. if (check(a, b) >= 0) {
  53. ++ret;
  54. }
  55. std::swap(b[i], b[j]);
  56. }
  57. }
  58. return ret;
  59. }
  60. ul T;
  61. ul a[25] = {0, 40, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30};
  62. ul b[25] = {0, 40, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30};
  63. std::mt19937_64 rnd;
  64. void sf(ul a[])
  65. {
  66. for (ul i = 24; i >= 1; --i) {
  67. std::swap(a[i], a[rnd() % i + 1]);
  68. }
  69. }
  70. std::pair<ul, ul> sp[500];
  71. ul tot;
  72. int main()
  73. {
  74. for (ul i = 1; i + 1 <= 24; ++i) {
  75. for (ul j = i + 1; j <= 24; ++j) {
  76. ++tot;
  77. sp[tot].first = i;
  78. sp[tot].second = j;
  79. }
  80. }
  81. rnd.seed(std::time(0));
  82. std::scanf("%u", &T);
  83. for (ul Case = 1; Case <= T; ++Case) {
  84. for (ul i = 1; i <= 24; ++i) {
  85. std::scanf("%u", &a[i]);
  86. }
  87. ul cnt = 0;
  88. while (true) {
  89. ul tmp = check2(a, b);
  90. while (tmp) {
  91. bool flag = false;
  92. for (ul i = tot; i >= 1; --i) {
  93. std::swap(sp[rnd() % i + 1], sp[i]);
  94. ul s = sp[i].first;
  95. ul t = sp[i].second;
  96. if (b[s] == b[t]) {
  97. continue;
  98. }
  99. std::swap(b[s], b[t]);
  100. ul tmp2 = check2(a, b);
  101. if (tmp2 < tmp) {
  102. tmp = tmp2;
  103. flag = true;
  104. break;
  105. }
  106. std::swap(b[s], b[t]);
  107. }
  108. if (!flag) {
  109. break;
  110. }
  111. }
  112. if (tmp == 0) {
  113. for (ul i = 1; i <= 24; ++i) {
  114. if (i != 1) {
  115. std::putchar(' ');
  116. }
  117. std::printf("%u", b[i]);
  118. }
  119. std::putchar('\n');
  120. break;
  121. }
  122. sf(b);
  123. }
  124. }
  125. return 0;
  126. }

G、Happiness

模拟

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul n;
  7. const ul maxn = 300;
  8. class problem {
  9. public:
  10. ul time = 0;
  11. ul pen = 0;
  12. };
  13. class person {
  14. public:
  15. problem p[11];
  16. ul cnt = 0;
  17. ul sum = 0;
  18. ul id = 0;
  19. };
  20. person guy[maxn + 1];
  21. std::string instr;
  22. std::stringstream ss;
  23. std::stringstream ss2;
  24. bool operator<(const person& a, const person& b)
  25. {
  26. if (a.cnt != b.cnt) {
  27. return a.cnt > b.cnt;
  28. }
  29. if (a.sum != b.sum) {
  30. return a.sum < b.sum;
  31. }
  32. for (ul i = 10 - a.cnt + 1; i <= 10; ++i) {
  33. if (a.p[i].time != b.p[i].time) {
  34. return a.p[i].time < b.p[i].time;
  35. }
  36. }
  37. return a.id > b.id;
  38. }
  39. person pang;
  40. ul set;
  41. ul mn[11];
  42. ul mnmn = 301;
  43. ul stack[11];
  44. int main()
  45. {
  46. std::getline(std::cin, instr);
  47. ss.clear();
  48. ss.str(instr);
  49. for (ul i = 1; i <= 10; ++i) {
  50. mn[i] = 301;
  51. }
  52. ss >> n;
  53. ul mx = 0;
  54. for (ul i = 1; i <= n - 1; ++i) {
  55. std::getline(std::cin, instr);
  56. ss.clear();
  57. ss.str(instr);
  58. guy[i].id = i;
  59. for (ul j = 1; j <= 10; ++j) {
  60. std::getline(ss, instr, ',');
  61. if (instr == "-") {
  62. guy[i].p[j].time = 301;
  63. guy[i].p[j].pen = 11;
  64. } else {
  65. ss2.clear();
  66. ss2.str(instr);
  67. ss2 >> guy[i].p[j].time >> guy[i].p[j].pen;
  68. ++guy[i].cnt;
  69. guy[i].sum += guy[i].p[j].time + guy[i].p[j].pen * 20;
  70. mx = std::max(mx, guy[i].p[j].time);
  71. mn[j] = std::min(mn[j], guy[i].p[j].time);
  72. mnmn = std::min(mnmn, mn[j]);
  73. }
  74. }
  75. std::sort(guy[i].p + 1, guy[i].p + 11, [](const problem& a, const problem& b){return a.time > b.time;});
  76. }
  77. std::sort(guy + 1, guy + n);
  78. std::getline(std::cin, instr);
  79. ss.clear();
  80. ss.str(instr);
  81. guy[n].id = n;
  82. for (ul j = 1; j <= 10; ++j) {
  83. std::getline(ss, instr, ',');
  84. if (instr == "-") {
  85. pang.p[j].time = 301;
  86. pang.p[j].pen = 11;
  87. } else {
  88. ss2.clear();
  89. ss2.str(instr);
  90. ss2 >> pang.p[j].time >> pang.p[j].pen;
  91. set |= 1 << j;
  92. }
  93. }
  94. ul ans = 0;
  95. for (ul mask = set; ; mask = mask - 1 & set) {
  96. ul tot = 0;
  97. ul sum = 0;
  98. for (ul i = 1; i <= 10; ++i) {
  99. if (mask >> i & 1) {
  100. ++tot;
  101. stack[tot] = i;
  102. sum += pang.p[i].time;
  103. }
  104. }
  105. if (sum > 300) {
  106. continue;
  107. }
  108. do {
  109. guy[n].cnt = tot;
  110. guy[n].sum = 0;
  111. for (ul i = 1; i <= 10; ++i) {
  112. guy[n].p[i].time = 301;
  113. guy[n].p[i].pen = 11;
  114. }
  115. ul currans = 0;
  116. ul cmx = 0;
  117. ul cmn = 301;
  118. for (ul i = 1; i <= tot; ++i) {
  119. guy[n].p[stack[i]].time = guy[n].p[stack[i - 1]].time + pang.p[stack[i]].time;
  120. guy[n].p[stack[i]].pen = pang.p[stack[i]].pen;
  121. guy[n].sum += guy[n].p[stack[i]].time + guy[n].p[stack[i]].pen * 20;
  122. cmx = std::max(guy[n].p[stack[i]].time, cmx);
  123. cmn = std::min(guy[n].p[stack[i]].time, cmn);
  124. if (guy[n].p[stack[i]].time <= mn[stack[i]]) {
  125. currans += 800;
  126. }
  127. }
  128. if (mask) {
  129. if (cmx >= mx) {
  130. currans += 500;
  131. }
  132. if (cmn <= mnmn) {
  133. currans += 700;
  134. }
  135. }
  136. std::sort(guy[n].p + 1, guy[n].p + 11, [](const problem& a, const problem& b){return a.time > b.time;});
  137. ul r = std::upper_bound(guy + 1, guy + n, guy[n]) - guy;
  138. currans += 5000 / r;
  139. if (r <= n / 10) {
  140. currans += 1200;
  141. } else if (r <= n / 10 * 3) {
  142. currans += 800;
  143. } else if (r <= n / 10 * 6) {
  144. currans += 400;
  145. }
  146. ans = std::max(ans, currans);
  147. } while (std::next_permutation(stack + 1, stack + tot + 1));
  148. if (!mask) {
  149. break;
  150. }
  151. }
  152. std::printf("%u\n", ans);
  153. return 0;
  154. }

H、king

首先假设有一合法结果,于是该结果的首尾下标差最大为,而由于其总共有至少个间隔,故最小间隔一定小于等于,注意时该值都等于,所以仅时单独处理。
现在设表示结果中大小为的间隔的数量,那么显然有以下两个不等式

由此可知
从而
所以只需要考虑满足以上条件的那些即可。注意所有的的总和小于等于,故满足上述条件的至多有,所以不用担心时间复杂度。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul n;
  7. const ul maxn = 2e5;
  8. ul p;
  9. ul b[maxn + 1];
  10. ul binv[maxn + 1];
  11. ul bpre[maxn + 1];
  12. ul bpreinv[maxn + 1];
  13. ul T;
  14. ul mul(ul a, ul b)
  15. {
  16. return ull(a) * ull(b) % p;
  17. }
  18. void exgcd(li a, li b, li& x, li& y)
  19. {
  20. if (b) {
  21. exgcd(b, a % b, y, x);
  22. y -= a / b * x;
  23. } else {
  24. x = 1;
  25. y = 0;
  26. }
  27. }
  28. ul inverse(ul a)
  29. {
  30. li x, y;
  31. exgcd(a, p, x, y);
  32. return x < 0 ? x + li(p) : x;
  33. }
  34. std::mt19937_64 rnd;
  35. class hashmap {
  36. public:
  37. class node {
  38. public:
  39. ul key = 0;
  40. ul val = 0;
  41. };
  42. bool ex[1 << 20];
  43. node v[1 << 20];
  44. ul sz;
  45. ul a;
  46. ul b;
  47. const ul mod = 1e9 + 7;
  48. void init(ul n)
  49. {
  50. a = rnd() % (mod - 1) + 1;
  51. b = rnd() % mod;
  52. sz = 1;
  53. while (sz + sz < n + n + n) {
  54. sz <<= 1;
  55. }
  56. std::memset(ex, false, sz * sizeof(bool));
  57. }
  58. ul& operator[](ul x)
  59. {
  60. ul h = (ull(x) * ull(a) + b) % mod & sz - 1;
  61. while (true) {
  62. if (!ex[h]) {
  63. ex[h] = true;
  64. v[h].key = x;
  65. v[h].val = 0;
  66. return v[h].val;
  67. }
  68. if (v[h].key == x) {
  69. return v[h].val;
  70. }
  71. h = h + 1 & sz - 1;
  72. }
  73. }
  74. };
  75. hashmap cnt;
  76. hashmap len;
  77. ul calc(ul q)
  78. {
  79. len.init(n + n);
  80. ul ret = 0;
  81. for (ul i = n; i >= 1; --i) {
  82. ul& l = len[b[i]];
  83. l = std::max(l, len[mul(b[i], q)] + 1);
  84. ret = std::max(ret, l);
  85. }
  86. return ret;
  87. }
  88. int main()
  89. {
  90. rnd.seed(std::time(0));
  91. std::scanf("%u", &T);
  92. for (ul Case = 1; Case <= T; ++Case) {
  93. std::scanf("%u%u", &n, &p);
  94. bpre[0] = 1;
  95. for (ul i = 1; i <= n; ++i) {
  96. std::scanf("%u", &b[i]);
  97. bpre[i] = mul(bpre[i - 1], b[i]);
  98. }
  99. bpreinv[n] = inverse(bpre[n]);
  100. for (ul i = n; i >= 1; --i) {
  101. bpreinv[i - 1] = mul(bpreinv[i], b[i]);
  102. binv[i] = mul(bpreinv[i], bpre[i - 1]);
  103. }
  104. ul ans = 0;
  105. if (n <= 4) {
  106. for (ul i = 1; i + 1 <= n; ++i) {
  107. for (ul j = i + 1; j <= n; ++j) {
  108. ul q = mul(b[j], binv[i]);
  109. ans = std::max(ans, calc(q));
  110. }
  111. }
  112. } else {
  113. cnt.init(n + n - 3);
  114. for (ul i = 1; i + 1 <= n; ++i) {
  115. for (ul j = i + 1; j <= n && j <= i + 2; ++j) {
  116. cnt[mul(b[j], binv[i])] += 3 ^ j - i;
  117. }
  118. }
  119. for (ul i = 0; i != cnt.sz; ++i) {
  120. if (!cnt.ex[i] || cnt.v[i].val < (n + 1) / 2 * 3 - n - 2) {
  121. continue;
  122. }
  123. ans = std::max(ans, calc(cnt.v[i].key));
  124. }
  125. }
  126. if (ans * 2 >= n) {
  127. std::printf("%u\n", ans);
  128. } else {
  129. std::printf("-1\n");
  130. }
  131. }
  132. return 0;
  133. }

I、Moon

牛客这道题没放spj,肏你妈。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using lll = __int128;
  7. using llf = long double;
  8. using lf = double;
  9. li sgn(lll x)
  10. {
  11. return x < 0 ? -1 : (x > 0 ? 1 : 0);
  12. }
  13. const lll bound = 1e18;
  14. bool less(lll a, lll b, lll c, lll d)
  15. {
  16. if (sgn(a) != sgn(c)) {
  17. return sgn(a) < sgn(c);
  18. }
  19. if (a < 0) {
  20. return less(-c, d, -a, b);
  21. }
  22. lll q1 = a / b;
  23. lll r1 = a - b * q1;
  24. lll q2 = c / d;
  25. lll r2 = c - d * q2;
  26. if (q1 != q2) {
  27. return q1 < q2;
  28. }
  29. if (r1 == 0 || r2 == 0) {
  30. return r1 < r2;
  31. }
  32. if (b <= bound && d <= bound) {
  33. return r1 * d < r2 * b;
  34. }
  35. return less(d, r2, b, r1);
  36. }
  37. ul n;
  38. const ul maxn = 1e5;
  39. lll in()
  40. {
  41. ll tmp;
  42. std::scanf("%lld", &tmp);
  43. return tmp;
  44. }
  45. class vec {
  46. public:
  47. lll x = 0;
  48. lll y = 0;
  49. lll z = 0;
  50. vec()=default;
  51. vec(lll a, lll b, lll c): x(a), y(b), z(c) {}
  52. };
  53. class vecd {
  54. public:
  55. llf x = 0;
  56. llf y = 0;
  57. llf z = 0;
  58. vecd()=default;
  59. vecd(llf a, llf b, llf c): x(a), y(b), z(c) {}
  60. vecd(const vec& a): x(a.x), y(a.y), z(a.z) {}
  61. };
  62. std::ostream& operator<<(std::ostream& os, const vecd& a)
  63. {
  64. return os << '{' << a.x << ',' << a.y << ',' << a.z << '}';
  65. }
  66. vec p[maxn + 1];
  67. vec p2[maxn + 1];
  68. std::vector<ul> stack1;
  69. std::vector<ul> stack2;
  70. std::vector<ul> stackpbuttom;
  71. std::vector<ul> stackptop;
  72. std::vector<ul> stacknbuttom;
  73. std::vector<ul> stackntop;
  74. std::vector<ul> stacktop;
  75. std::vector<ul> stackbuttom;
  76. lll gcd(lll a, lll b)
  77. {
  78. a = a < 0 ? -a : a;
  79. b = b < 0 ? -b : b;
  80. while (b) {
  81. b ^= a ^= b ^= a %= b;
  82. }
  83. return a;
  84. }
  85. vec operator^(const vec& a, const vec& b)
  86. {
  87. vec ret = vec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
  88. lll g = gcd(gcd(ret.x, ret.y), ret.z);
  89. if (g) {
  90. ret.x /= g;
  91. ret.y /= g;
  92. ret.z /= g;
  93. }
  94. return ret;
  95. }
  96. vec operator-(const vec& a)
  97. {
  98. return vec(-a.x, -a.y, -a.z);
  99. }
  100. vecd operator-(const vecd& a, const vecd& b)
  101. {
  102. return vecd(a.x - b.x, a.y - b.y, a.z - b.z);
  103. }
  104. vecd operator^(const vecd& a, const vecd& b)
  105. {
  106. return vecd(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
  107. }
  108. lll operator*(const vec& a, const vec& b)
  109. {
  110. return a.x * b.x + a.y * b.y + a.z * b.z;
  111. }
  112. llf operator*(const vecd& a, const vecd& b)
  113. {
  114. return a.x * b.x + a.y * b.y + a.z * b.z;
  115. }
  116. vecd operator*(llf a, const vecd& b)
  117. {
  118. return vecd(a * b.x, a * b.y, a * b.z);
  119. }
  120. vecd operator*(const vecd& a, llf b)
  121. {
  122. return vecd(a.x * b, a.y * b, a.z * b);
  123. }
  124. vecd operator/(const vecd& a, llf b)
  125. {
  126. return vecd(a.x / b, a.y / b, a.z / b);
  127. }
  128. llf norm(const vecd& a)
  129. {
  130. return std::sqrt(a * a);
  131. }
  132. vecd normalize(const vecd& a)
  133. {
  134. llf len = std::max(std::max(a.x < 0 ? -a.x : a.x, a.y < 0 ? -a.y : a.y), a.z < 0 ? -a.z : a.z);
  135. if (!len) {
  136. return a;
  137. }
  138. vecd b = a / len;
  139. auto n = norm(b);
  140. return b / n;
  141. }
  142. lll det(const vec& a, const vec& b, const vec& c)
  143. {
  144. return a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y - a.z * b.y * c.x - a.y * b.x * c.z - a.x * b.z * c.y;
  145. }
  146. void gethull(std::vector<ul>& stack1, std::vector<ul>& stack2, std::vector<ul>& stack3)
  147. {
  148. std::sort(stack1.begin(), stack1.end(), [&](ul i, ul j){
  149. const vec& a = p[i];
  150. const vec& b = p[j];
  151. if ((a.z == 0) != (b.z == 0)) {
  152. return a.z == 0;
  153. }
  154. if (a.z && b.z) {
  155. return a.x * b.z != b.x * a.z ? a.x * b.z < b.x * a.z : a.y * b.z > b.y * a.z;
  156. }
  157. if ((a.x == 0) != (b.x == 0)) {
  158. return a.x == 0;
  159. }
  160. if (a.x && b.x) {
  161. return a.y * b.x < b.y * a.x;
  162. }
  163. return false;
  164. });
  165. stack2.resize(0);
  166. for (auto i : stack1) {
  167. while (stack2.size() >= 2) {
  168. const vec& a = p[stack2[stack2.size() - 2]];
  169. const vec& b = p[stack2[stack2.size() - 1]];
  170. const vec& c = p[i];
  171. bool flag = det(a, b, c) <= 0;
  172. if (flag) {
  173. stack2.pop_back();
  174. } else {
  175. break;
  176. }
  177. }
  178. stack2.push_back(i);
  179. }
  180. std::reverse(stack1.begin(), stack1.end());
  181. stack3.resize(0);
  182. for (auto i : stack1) {
  183. while (stack3.size() >= 2) {
  184. const vec& a = p[stack3[stack3.size() - 2]];
  185. const vec& b = p[stack3[stack3.size() - 1]];
  186. const vec& c = p[i];
  187. bool flag = det(a, b, c) <= 0;
  188. if (flag) {
  189. stack3.pop_back();
  190. } else {
  191. break;
  192. }
  193. }
  194. stack3.push_back(i);
  195. }
  196. }
  197. void gethulld(std::vector<ul>& stack1, std::vector<ul>& stack2, std::vector<ul>& stack3)
  198. {
  199. std::sort(stack1.begin(), stack1.end(), [&](ul i, ul j){
  200. const vec& a = p2[i];
  201. const vec& b = p2[j];
  202. if ((a.z == 0) != (b.z == 0)) {
  203. return a.z == 0;
  204. }
  205. if (a.z && b.z) {
  206. bool flag1 = less(b.x, b.z, a.x, a.z);
  207. bool flag2 = less(a.x, a.z, b.x, b.z);
  208. return (flag1 || flag2) ? flag2 : less(a.y, a.z, b.y, b.z);
  209. }
  210. if ((a.x == 0) != (b.x == 0)) {
  211. return a.x == 0;
  212. }
  213. if (a.x && b.x) {
  214. return less(-a.y, -a.x, -b.y, -b.x);
  215. }
  216. return false;
  217. });
  218. stack2.resize(0);
  219. for (auto i : stack1) {
  220. while (stack2.size() >= 2) {
  221. const vec& a = p[stack2[stack2.size() - 2]];
  222. const vec& b = p[stack2[stack2.size() - 1]];
  223. const vec& c = p[i];
  224. bool flag = det(a, b, c) <= 0;
  225. if (flag) {
  226. stack2.pop_back();
  227. } else {
  228. break;
  229. }
  230. }
  231. stack2.push_back(i);
  232. }
  233. std::reverse(stack1.begin(), stack1.end());
  234. stack3.resize(0);
  235. for (auto i : stack1) {
  236. while (stack3.size() >= 2) {
  237. const vec& a = p[stack3[stack3.size() - 2]];
  238. const vec& b = p[stack3[stack3.size() - 1]];
  239. const vec& c = p[i];
  240. bool flag = det(a, b, c) <= 0;
  241. if (flag) {
  242. stack3.pop_back();
  243. } else {
  244. break;
  245. }
  246. }
  247. stack3.push_back(i);
  248. }
  249. }
  250. bool out(const vec& a, const vec& b, const vec& c)
  251. {
  252. return det(a, b, c) <= 0;
  253. }
  254. llf myacos(llf a)
  255. {
  256. return std::acos(std::max(std::min(a, llf(1)), llf(-1)));
  257. }
  258. llf cnt(const vec& a, const vec& b, const vec& c)
  259. {
  260. return myacos((normalize(normalize(a) ^ normalize(b)) * normalize(normalize(b) ^ normalize(c))));
  261. }
  262. bool operator==(const vec& a, const vec& b)
  263. {
  264. return a.x == b.x && a.y == b.y && a.z == b.z;
  265. }
  266. const llf pi = std::acos(llf(-1));
  267. const llf hpi = pi * llf(0.5);
  268. std::priority_queue<llf, std::vector<llf>, std::greater<llf>> heap;
  269. int main()
  270. {
  271. std::scanf("%u", &n);
  272. if (n <= 2) {
  273. std::printf("1.0\n");
  274. return 0;
  275. }
  276. for (ul i = 1; i <= n; ++i) {
  277. p[i].x = in();
  278. p[i].y = in();
  279. p[i].z = in();
  280. lll g = gcd(gcd(p[i].x, p[i].y), p[i].z);
  281. p[i].x /= g;
  282. p[i].y /= g;
  283. p[i].z /= g;
  284. }
  285. stack1.resize(0);
  286. for (ul i = 1; i <= n; ++i) {
  287. if (p[i].z > 0 || p[i].z == 0 && p[i].x < 0 || p[i].z == 0 && p[i].x == 0 && p[i].y > 0) {
  288. stack1.push_back(i);
  289. }
  290. }
  291. gethull(stack1, stackpbuttom, stackptop);
  292. stack1.resize(0);
  293. for (ul i = 1; i <= n; ++i) {
  294. if (p[i].z < 0 || p[i].z == 0 && p[i].x > 0 || p[i].z == 0 && p[i].x == 0 && p[i].y < 0) {
  295. stack1.push_back(i);
  296. p[i].x = -p[i].x;
  297. p[i].y = -p[i].y;
  298. p[i].z = -p[i].z;
  299. }
  300. }
  301. gethull(stack1, stacknbuttom, stackntop);
  302. ul s = 0;
  303. ul t = 0;
  304. vec zdi;
  305. vec xdi;
  306. vec ydi;
  307. vecd zdir;
  308. vecd xdir;
  309. vecd ydir;
  310. if (!stackpbuttom.size() || !stacknbuttom.size()) {
  311. zdir = zdi = vec(0, 0, 1);
  312. ydir = ydi = vec(0, 1, 0);
  313. xdir = xdi = vec(1, 0, 0);
  314. } else {
  315. ul s = 0;
  316. ul t = 0;
  317. for (ul i = 0; i + 1 < stackpbuttom.size() && !s && !t; ++i) {
  318. const vec& a = p[stackpbuttom[i]];
  319. const vec& b = p[stackpbuttom[i + 1]];
  320. ul l = 0, r = stackntop.size();
  321. while (l + 1 != r) {
  322. ul mid = l + r >> 1;
  323. const vec& c = p[stackntop[mid - 1]];
  324. const vec& d = p[stackntop[mid]];
  325. bool flag = (a ^ b) * (normalize(d) - normalize(c)) >= 0;
  326. if (flag) {
  327. l = mid;
  328. } else {
  329. r = mid;
  330. }
  331. }
  332. const vec& c = p[stackntop[l]];
  333. if (out(a, b, c)) {
  334. s = stackpbuttom[i];
  335. t = stackpbuttom[i + 1];
  336. }
  337. }
  338. for (ul i = 0; i + 1 < stacknbuttom.size() && !s && !t; ++i) {
  339. const vec& a = p[stacknbuttom[i]];
  340. const vec& b = p[stacknbuttom[i + 1]];
  341. ul l = 0, r = stackptop.size();
  342. while (l + 1 != r) {
  343. ul mid = l + r >> 1;
  344. const vec& c = p[stackptop[mid - 1]];
  345. const vec& d = p[stackptop[mid]];
  346. bool flag = (a ^ b) * (normalize(d) - normalize(c)) >= 0;
  347. if (flag) {
  348. l = mid;
  349. } else {
  350. r = mid;
  351. }
  352. }
  353. const vec& c = p[stackptop[l]];
  354. if (out(a, b, c)) {
  355. t = stacknbuttom[i];
  356. s = stacknbuttom[i + 1];
  357. }
  358. }
  359. for (ul i = 0; i + 1 < stackptop.size() && !s && !t; ++i) {
  360. const vec& a = p[stackptop[i]];
  361. const vec& b = p[stackptop[i + 1]];
  362. ul l = 0, r = stacknbuttom.size();
  363. while (l + 1 != r) {
  364. ul mid = l + r >> 1;
  365. const vec& c = p[stacknbuttom[mid - 1]];
  366. const vec& d = p[stacknbuttom[mid]];
  367. bool flag = (a ^ b) * (normalize(d) - normalize(c)) >= 0;
  368. if (flag) {
  369. l = mid;
  370. } else {
  371. r = mid;
  372. }
  373. }
  374. const vec& c = p[stacknbuttom[l]];
  375. if (out(a, b, c)) {
  376. s = stackptop[i];
  377. t = stackptop[i + 1];
  378. }
  379. }
  380. for (ul i = 0; i + 1 < stackntop.size() && !s && !t; ++i) {
  381. const vec& a = p[stackntop[i]];
  382. const vec& b = p[stackntop[i + 1]];
  383. ul l = 0, r = stackpbuttom.size();
  384. while (l + 1 != r) {
  385. ul mid = l + r >> 1;
  386. const vec& c = p[stackpbuttom[mid - 1]];
  387. const vec& d = p[stackpbuttom[mid]];
  388. bool flag = (a ^ b) * (normalize(d) - normalize(c)) >= 0;
  389. if (flag) {
  390. l = mid;
  391. } else {
  392. r = mid;
  393. }
  394. }
  395. const vec& c = p[stackpbuttom[l]];
  396. if (out(a, b, c)) {
  397. t = stackntop[i];
  398. s = stackntop[i + 1];
  399. }
  400. }
  401. if (!s && !t) {
  402. std::printf("0.0\n");
  403. return 0;
  404. }
  405. for (ul i : stack1) {
  406. p[i].x = -p[i].x;
  407. p[i].y = -p[i].y;
  408. p[i].z = -p[i].z;
  409. }
  410. zdi = p[s] ^ p[t];
  411. ydi = p[s];
  412. xdi = ydi ^ zdi;
  413. stack1.resize(0);
  414. stack2.resize(0);
  415. for (ul i = 1; i <= n; ++i) {
  416. if (p[i] * zdi == 0) {
  417. if (p[i] * xdi < 0 || p[i] * xdi == 0 && p[i] * ydi > 0) {
  418. stack1.push_back(i);
  419. } else {
  420. stack2.push_back(i);
  421. }
  422. }
  423. }
  424. std::sort(stack1.begin(), stack1.end(), [&](ul i, ul j){
  425. const vec& a = p[i];
  426. const vec& b = p[j];
  427. lll ax = a * xdi;
  428. lll bx = b * xdi;
  429. lll ay = a * ydi;
  430. lll by = b * ydi;
  431. if ((ax == 0) != (bx == 0)) {
  432. return ax == 0;
  433. }
  434. if (ax && bx) {
  435. return less(-ay, -ax, -by, -bx);
  436. }
  437. return false;
  438. });
  439. std::sort(stack2.begin(), stack2.end(), [&](ul i, ul j){
  440. const vec& a = p[i];
  441. const vec& b = p[j];
  442. lll ax = a * xdi;
  443. lll bx = b * xdi;
  444. lll ay = a * ydi;
  445. lll by = b * ydi;
  446. if ((ax == 0) != (bx == 0)) {
  447. return ax == 0;
  448. }
  449. if (ax && bx) {
  450. return less(ay, ax, by, bx);
  451. }
  452. return false;
  453. });
  454. if (stack2.empty()) {
  455. xdir = normalize(xdi);
  456. ydir = normalize(ydi);
  457. zdir = normalize(zdi);
  458. } else {
  459. const vec& a = p[stack1.back()];
  460. const vec& b = p[stack2.front()];
  461. lll ax = a * xdi;
  462. lll bx = b * xdi;
  463. lll ay = a * ydi;
  464. lll by = b * ydi;
  465. if (ax == 0 && bx != 0 || ax != 0 && bx != 0 && less(-ay, -ax, by, bx)) {
  466. zdi = b ^ a;
  467. ydi = b;
  468. xdi = ydi ^ zdi;
  469. xdir = normalize(xdi);
  470. ydir = normalize(ydi);
  471. zdir = normalize(zdi);
  472. } else if (p[stack2.back()] * xdi != 0 && ax != 0 && (bx == 0 || less(by, bx, -ay, -ax))) {
  473. for (ul i = 1; i <= n; ++i) {
  474. if (p[i] * zdi > 0) {
  475. std::printf("0.5\n");
  476. return 0;
  477. }
  478. }
  479. std::printf("1.0\n");
  480. return 0;
  481. } else {
  482. xdi = -zdi;
  483. zdi = b;
  484. ydi = zdi ^ xdi;
  485. xdir = normalize(xdi);
  486. ydir = normalize(ydi);
  487. zdir = normalize(zdi);
  488. stack1.resize(0);
  489. for (ul i = 1; i <= n; ++i) {
  490. if (p[i] * xdi != 0 || p[i] * ydi != 0) {
  491. stack1.push_back(i);
  492. }
  493. }
  494. std::sort(stack1.begin(), stack1.end(), [&](ul i, ul j){
  495. const vec& a = p[i];
  496. const vec& b = p[j];
  497. lll ax = a * xdi;
  498. lll bx = b * xdi;
  499. lll ay = a * ydi;
  500. lll by = b * ydi;
  501. if (ax && bx) {
  502. return less(-ay, -ax, -by, -bx);
  503. }
  504. if (!ax && !bx) {
  505. return (ay > 0) > (by > 0);
  506. }
  507. if (ax && !bx) {
  508. return by < 0;
  509. }
  510. if (!ax && bx) {
  511. return ay > 0;
  512. }
  513. return false;
  514. });
  515. vecd u = normalize(vecd(p[stack1.front()] * xdir, p[stack1.front()] * ydir, 0));
  516. vecd v = normalize(vecd(p[stack1.back()] * xdir, p[stack1.back()] * ydir, 0));
  517. std::printf("%.12lf\n", lf(llf(1) - myacos(u * v) / pi / llf(2)));
  518. return 0;
  519. }
  520. }
  521. }
  522. for (ul i = 1; i <= n; ++i) {
  523. p2[i] = vec(p[i] * xdi, p[i] * ydi, p[i] * zdi);
  524. }
  525. stack1.resize(0);
  526. for (ul i = 1; i <= n; ++i) {
  527. stack1.push_back(i);
  528. }
  529. gethulld(stack1, stackbuttom, stacktop);
  530. llf ans = 0;
  531. for (ul i = 0; i + 2 < stackbuttom.size(); ++i) {
  532. heap.push(cnt(p[stackbuttom[i]], p[stackbuttom[i + 1]], p[stackbuttom[i + 2]]));
  533. }
  534. for (ul i = 0; i + 2 < stacktop.size(); ++i) {
  535. heap.push(cnt(p[stacktop[i]], p[stacktop[i + 1]], p[stacktop[i + 2]]));
  536. }
  537. heap.push(cnt(p[stackbuttom[stackbuttom.size() - 2]], p[stacktop[0]], p[stacktop[1]]));
  538. heap.push(cnt(p[stacktop[stacktop.size() - 2]], p[stackbuttom[0]], p[stackbuttom[1]]));
  539. while (heap.size() >= 2) {
  540. llf a = heap.top();
  541. heap.pop();
  542. llf b = heap.top();
  543. heap.pop();
  544. heap.push(a + b);
  545. }
  546. ans = heap.top() + pi + pi;
  547. std::printf("%.12lf\n", lf(ans / pi / llf(4)));
  548. return 0;
  549. }

J、Permutation

考虑这样一个状态:区间中左边区域中的数(除了某个别)可以随便乱排,右边区域中的数(除了某个别)可以随便乱排,第一个大情况是左边和右边无交,那么现在假设中最小的数在处,如果中,那么说明的可行范围就是,而剩余问题化为,如果中,那么说明的可行范围就是,而剩余问题化为,如果在上述两个区间之外,说明不能被移动,问题化为,第二个大情况是有交,说明剩余数都可以乱排。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul mod = 998244353;
  7. ul plus(ul a, ul b)
  8. {
  9. return a + b < mod ? a + b : a + b - mod;
  10. }
  11. ul minus(ul a, ul b)
  12. {
  13. return a < b ? a + mod - b : a - b;
  14. }
  15. ul mul(ul a, ul b)
  16. {
  17. return ull(a) * ull(b) % mod;
  18. }
  19. ul T;
  20. ul n, c;
  21. ul sz;
  22. const ul mxsz = 1 << 19;
  23. const ul maxn = 5e5;
  24. ul fac[maxn + 1];
  25. ul v[maxn + 1];
  26. ul tree[mxsz << 1];
  27. ul query(ul l, ul r)
  28. {
  29. ul ret = 0;
  30. for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {
  31. if (~l & 1) {
  32. ret = v[ret] < v[tree[l ^ 1]] ? ret : tree[l ^ 1];
  33. }
  34. if (r & 1) {
  35. ret = v[ret] < v[tree[r ^ 1]] ? ret : tree[r ^ 1];
  36. }
  37. }
  38. return ret;
  39. }
  40. void change(ul pos, ul val)
  41. {
  42. v[pos] = val;
  43. for (pos |= sz, pos >>= 1; pos; pos >>= 1) {
  44. tree[pos] = v[tree[pos << 1]] < v[tree[pos << 1 | 1]] ? tree[pos << 1] : tree[pos << 1 | 1];
  45. }
  46. }
  47. void build(ul n)
  48. {
  49. sz = 1;
  50. while (n + 2 > sz) {
  51. sz <<= 1;
  52. }
  53. tree[sz] = 0;
  54. for (ul i = 1; i <= n; ++i) {
  55. tree[sz | i] = i;
  56. }
  57. for (ul i = n + 1; i != sz; ++i) {
  58. tree[sz | i] = 0;
  59. }
  60. for (ul i = sz - 1; i; --i) {
  61. tree[i] = v[tree[i << 1]] < v[tree[i << 1 | 1]] ? tree[i << 1] : tree[i << 1 | 1];
  62. }
  63. }
  64. ul search(ul l, ul r, ul x, ul y)
  65. {
  66. if (r - l + 1 < (x + y) * c) {
  67. return fac[r - l + 1 - std::max(x, ul(1)) + 1 - std::max(y, ul(1)) + 1];
  68. }
  69. ul cut = query(l, r);
  70. if (cut + 1 <= l + x * c) {
  71. change(cut, maxn + 1);
  72. return mul(x * c - (x - 1), search(l, r, x + 1, y));
  73. }
  74. if (cut + y * c >= r + 1) {
  75. change(cut, maxn + 1);
  76. return mul(y * c - (y - 1), search(l, r, x, y + 1));
  77. }
  78. return mul(search(l, cut - 1, x, cut - l >= c ? 1 : 0), search(cut + 1, r, r - cut >= c ? 1 : 0, y));
  79. }
  80. int main()
  81. {
  82. fac[0] = 1;
  83. for (ul i = 1; i <= maxn; ++i) {
  84. fac[i] = mul(fac[i - 1], i);
  85. }
  86. std::scanf("%u", &T);
  87. v[0] = maxn + 1;
  88. for (ul Case = 1; Case <= T; ++Case) {
  89. std::scanf("%u%u", &n, &c);
  90. for (ul i = 1; i <= n; ++i) {
  91. std::scanf("%u", &v[i]);
  92. }
  93. build(n);
  94. std::printf("%u\n", search(1, n, 0, 0));
  95. }
  96. return 0;
  97. }

K、All Pair Maximum Flow

  对于一个简单无向平面图(已经给出了到平面的嵌入),可以将边分为三类:连杆、外边、内边。考虑图的所有点双连通分量,在这些分量之外的边叫做连杆,对于一个点双连通分量,其最大的圈上的边叫做外边,其余边叫做内边。再将点分为两类:外点、内点。所有连杆以及外边上的点都叫外点,其余点都叫内点。
  如果没有点双连通分量,则其显然为一个森林,如果其有点双连通分量,任取其一,称为。现考虑记该点双连通分量的最大圈为中容量最小的边记为(如果有多个,任取其中一个即可),所在的圈中肯定有最小的,该圈记为。现在考虑建立一个新图,将中所有边的边权增加的边权,再把的边权改为,这样得到的新容量网络叫做。现在证明,对任何两个外点,在中能够分离的最小割和中能够分离的最小割是相等的。
  首先说明,无论在还是在中都有如下命题成立:如果存在有中边的最小割,那么存在刚好有中两条边,且刚好有中两条边,且其中一条边是的最小割。首先根据平面性以及都是外点可知,有中边的最小割一定可以刚好有的两条边,且刚好有的两条边(严格在拓扑里说清楚这一点并不平凡),如果此割没有,则考虑将从中边到中边的其中一系列边换成,总有一个系列满足换完之后依旧是分离的割,且由于中容量最小的边,该换边行为并不会导致割增大。
  接着注意到,任何满足“没中边,或者,存在刚好有中两条边,且刚好有中两条边,且其中一条边是”的割,在中的值一定是相等的,因为正好在的边权的减少量就是别的边的增加量,故在中能够分离的最小割和中能够分离的最小割是相等的。
  接着,可以靠此方法,将中的边砍掉得到新图,该过程一直执行下去,直到最后得到一个森林,之后就很简单了。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using llf = long double;
  7. const ul maxn = 2e5;
  8. ul n, m;
  9. std::map<ul, ull> graph[maxn + 1];
  10. ul next(ul a, ul b)
  11. {
  12. auto it = std::next(graph[b].find(a));
  13. return it == graph[b].end() ? graph[b].begin()->first : it->first;
  14. }
  15. class vec {
  16. public:
  17. ll x = 0;
  18. ll y = 0;
  19. vec()=default;
  20. vec(ll a, ll b): x(a), y(b) {}
  21. };
  22. vec operator+(const vec& a, const vec& b)
  23. {
  24. return vec(a.x + b.x, a.y + b.y);
  25. }
  26. vec operator-(const vec& a, const vec& b)
  27. {
  28. return vec(a.x - b.x, a.y - b.y);
  29. }
  30. ll operator*(const vec& a, const vec& b)
  31. {
  32. return a.x * b.x + a.y * b.y;
  33. }
  34. ll operator^(const vec& a, const vec& b)
  35. {
  36. return a.x * b.y - a.y * b.x;
  37. }
  38. ul tot = 0;
  39. vec p[maxn + 1];
  40. const ll tau = 104653;
  41. ll lowersqrt(ll x)
  42. {
  43. ll tmp = std::llround(std::sqrt(llf(x)));
  44. if (tmp * tmp > x) {
  45. --tmp;
  46. }
  47. return tmp;
  48. }
  49. std::mt19937_64 rnd;
  50. using pulul = std::pair<ul, ul>;
  51. class hashmap {
  52. public:
  53. class node {
  54. public:
  55. pulul key;
  56. ul val = 0;
  57. };
  58. bool ex[1 << 22];
  59. node v[1 << 22];
  60. ul sz;
  61. ul a;
  62. ul b;
  63. ul c;
  64. const ul mod = 1e9 + 7;
  65. void init(ul n)
  66. {
  67. a = rnd() % (mod - 1) + 1;
  68. b = rnd() % (mod - 1) + 1;
  69. c = rnd() % mod;
  70. sz = 1;
  71. while (sz + sz < n + n + n) {
  72. sz <<= 1;
  73. }
  74. std::memset(ex, false, sz * sizeof(bool));
  75. }
  76. ul& operator[](const pulul& x)
  77. {
  78. ul h = (ull(x.first) * ull(a) + ull(x.second) * ull(b) + ull(c)) % mod & sz - 1;
  79. while (true) {
  80. if (!ex[h]) {
  81. ex[h] = true;
  82. v[h].key = x;
  83. v[h].val = 0;
  84. return v[h].val;
  85. }
  86. if (v[h].key == x) {
  87. return v[h].val;
  88. }
  89. h = h + 1 & sz - 1;
  90. }
  91. }
  92. };
  93. hashmap state;
  94. ul stack[maxn + 1];
  95. using pullpulul = std::pair<ull, pulul>;
  96. std::priority_queue<pullpulul, std::vector<pullpulul>, std::greater<pullpulul>> heap;
  97. std::priority_queue<pullpulul> heap2;
  98. ul fa[maxn + 1];
  99. ul rk[maxn + 1];
  100. ul cnt[maxn + 1];
  101. ul getfather(ul x)
  102. {
  103. return x == fa[x] ? x : fa[x] = getfather(fa[x]);
  104. }
  105. void connect(ul x, ul y)
  106. {
  107. x = getfather(x);
  108. y = getfather(y);
  109. if (rk[x] < rk[y]) {
  110. fa[x] = y;
  111. cnt[y] += cnt[x];
  112. } else if (rk[x] > rk[y]) {
  113. fa[y] = x;
  114. cnt[x] += cnt[y];
  115. } else {
  116. fa[x] = y;
  117. cnt[y] += cnt[x];
  118. ++rk[y];
  119. }
  120. }
  121. const ul mod = 998244353;
  122. ul plus(ul a, ul b)
  123. {
  124. return a + b < mod ? a + b : a + b - mod;
  125. }
  126. ul mul(ul a, ul b)
  127. {
  128. return ull(a) * ull(b) % mod;
  129. }
  130. int main()
  131. {
  132. rnd.seed(std::time(0));
  133. for (vec a(1, 0); a.x * a.x <= tau; ++a.x) {
  134. ll t = lowersqrt(tau - a.x * a.x);
  135. for (a.y = 0; a.y <= t; ++a.y) {
  136. if (std::__gcd(a.x, a.y < 0 ? -a.y : a.y) != 1) {
  137. continue;
  138. }
  139. ++tot;
  140. p[tot] = a;
  141. }
  142. }
  143. std::sort(p + 1, p + tot + 1, [](const vec& a, const vec& b){return a.y * b.x < b.y * a.x;});
  144. for (ul i = tot + 1; i <= maxn; ++i) {
  145. p[i] = vec(-p[i - tot].y, p[i - tot].x);
  146. }
  147. for (ul i = 2; i <= maxn; ++i) {
  148. p[i] = p[i - 1] + p[i];
  149. }
  150. std::scanf("%u%u", &n, &m);
  151. for (ul i = 1; i <= m; ++i) {
  152. ul u, v;
  153. ull c;
  154. std::scanf("%u%u%llu", &u, &v, &c);
  155. graph[u][v] = c;
  156. graph[v][u] = c;
  157. }
  158. state.init(m + m);
  159. for (ul s = 1; s <= n; ++s) {
  160. for (auto& e : graph[s]) {
  161. ul t = e.first;
  162. if (state[pulul(s, t)]) {
  163. continue;
  164. }
  165. ul tot = 1;
  166. stack[1] = s;
  167. ll sum = 0;
  168. for (ul i = s, j = t; ; ) {
  169. sum += p[i] ^ p[j];
  170. if (j == s) {
  171. break;
  172. }
  173. ++tot;
  174. stack[tot] = j;
  175. ul nexj = next(i, j);
  176. i = j;
  177. j = nexj;
  178. }
  179. stack[0] = stack[tot];
  180. ul tmp = sum < 0 ? 1 : 2;
  181. for (ul i = 1; i <= tot; ++i) {
  182. ul s = stack[i - 1];
  183. ul t = stack[i];
  184. if (tmp == 2) {
  185. heap.push(pullpulul(graph[s][t], pulul(s, t)));
  186. }
  187. state[pulul(s, t)] = tmp;
  188. }
  189. }
  190. }
  191. while (heap.size()) {
  192. auto c = heap.top();
  193. heap.pop();
  194. if (state[pulul(c.second.second, c.second.first)] == 2) {
  195. continue;
  196. }
  197. if (graph[c.second.first][c.second.second] != c.first) {
  198. continue;
  199. }
  200. for (ul i = c.second.first, j = next(c.second.second, c.second.first); j != c.second.first; ) {
  201. ull a = graph[i][j] += c.first;
  202. graph[j][i] += c.first;
  203. state[pulul(i, j)] = 2;
  204. heap.push(pullpulul(a, pulul(i, j)));
  205. ul nexj = next(i, j);
  206. i = j;
  207. j = nexj;
  208. }
  209. graph[c.second.first].erase(c.second.second);
  210. graph[c.second.second].erase(c.second.first);
  211. }
  212. for (ul i = 1; i <= n; ++i) {
  213. cnt[i] = 1;
  214. fa[i] = i;
  215. }
  216. for (ul i = 1; i <= n; ++i) {
  217. for (auto& e : graph[i]) {
  218. if (e.first > i) {
  219. break;
  220. }
  221. heap2.push(pullpulul(e.second, pulul(i, e.first)));
  222. }
  223. }
  224. ul ans = 0;
  225. while (heap2.size()) {
  226. auto c = heap2.top();
  227. heap2.pop();
  228. ul x = getfather(c.second.first);
  229. ul y = getfather(c.second.second);
  230. ans = plus(ans, mul(c.first % mod, mul(cnt[x], cnt[y])));
  231. connect(x, y);
  232. }
  233. std::printf("%u\n", ans);
  234. return 0;
  235. }

L、

M、value

对每个非幂,考虑所有的幂,总共个,子集枚举。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul maxn = 1e5;
  7. ul n;
  8. li a[maxn + 1];
  9. li b[maxn + 1];
  10. bool al[maxn + 1];
  11. ll ans = 0;
  12. ul js[18];
  13. ll tans[1 << 17];
  14. li minus[1 << 17][17];
  15. int main()
  16. {
  17. std::scanf("%u", &n);
  18. for (ul i = 1; i <= n; ++i) {
  19. std::scanf("%d", &a[i]);
  20. }
  21. for (ul i = 1; i <= n; ++i) {
  22. std::scanf("%d", &b[i]);
  23. }
  24. ul tot = 31 - __builtin_clz(n);
  25. for (ul mask = 2; mask < (1 << tot + 1); mask += 2) {
  26. for (ul cmask = mask; cmask; cmask ^= 1 << __builtin_ctz(cmask)) {
  27. ul i = __builtin_ctz(cmask);
  28. for (ul j = i << 1; j <= tot; j += i) {
  29. if (mask >> j & 1) {
  30. ++minus[mask][j];
  31. }
  32. }
  33. }
  34. }
  35. ans = a[1];
  36. for (ul i = 2; i <= n; ++i) {
  37. if (al[i]) {
  38. continue;
  39. }
  40. ul tot = 0;
  41. for (ull j = i; j <= n; j *= i) {
  42. ++tot;
  43. js[tot] = j;
  44. al[j] = true;
  45. }
  46. ll mx = 0;
  47. tans[0] = 0;
  48. for (ul mask = 2; mask < (1 << tot + 1); mask += 2) {
  49. ul id = 31 - __builtin_clz(mask);
  50. tans[mask] = tans[mask ^ 1 << id] + a[js[id]];
  51. ll tt = tans[mask];
  52. for (ul j = 1; j <= tot; ++j) {
  53. tt -= ll(minus[mask][j]) * ll(b[js[j]]);
  54. }
  55. mx = std::max(mx, tt);
  56. }
  57. ans += mx;
  58. }
  59. std::printf("%lld\n", ans);
  60. return 0;
  61. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注