[关闭]
@qq290637843 2021-01-08T06:28:52.000000Z 字数 21860 阅读 265

2020杭电第二场

A、Total Eclipse 6763

简单题

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  5. using ul = std::uint32_t;
  6. using li = std::int32_t;
  7. using ull = std::uint64_t;
  8. using ll = std::int64_t;
  9. ul T;
  10. const ul maxn = 1e5;
  11. ul n, m;
  12. ul rk[maxn + 1];
  13. ul fa[maxn + 1];
  14. std::map<ul, std::vector<ul>> b;
  15. ul getfather(ul x)
  16. {
  17. return x == fa[x] ? x : fa[x] = getfather(fa[x]);
  18. }
  19. bool connect(ul a, ul b)
  20. {
  21. a = getfather(a);
  22. b = getfather(b);
  23. if (a == b) {
  24. return false;
  25. } else if (rk[a] > rk[b]) {
  26. fa[b] = a;
  27. } else if (rk[b] > rk[a]) {
  28. fa[a] = b;
  29. } else {
  30. fa[a] = b;
  31. ++rk[b];
  32. }
  33. return true;
  34. }
  35. std::vector<ul> edge[maxn + 1];
  36. bool al[maxn + 1];
  37. int main()
  38. {
  39. std::ios::sync_with_stdio(false);
  40. std::cin.tie(0);
  41. iss.tie(0);
  42. oss.tie(0);
  43. std::getline(std::cin, instr, char(0));
  44. iss.str(instr);
  45. iss >> T;
  46. for (ul Case = 1; Case <= T; ++Case) {
  47. iss >> n >> m;
  48. b.clear();
  49. for (ul i = 1; i <= n; ++i) {
  50. al[i] = false;
  51. edge[i].resize(0);
  52. ul t;
  53. iss >> t;
  54. b[t].push_back(i);
  55. rk[i] = 0;
  56. fa[i] = i;
  57. }
  58. for (ul i = 1; i <= m; ++i) {
  59. ul u, v;
  60. iss >> u >> v;
  61. edge[u].push_back(v);
  62. edge[v].push_back(u);
  63. }
  64. b[0];
  65. ul cnt = 0;
  66. ull ans = 0;
  67. for (auto it = b.rbegin(), nit = std::next(it); nit != b.rend(); it = nit, ++nit) {
  68. for (ul u : it->second) {
  69. ++cnt;
  70. al[u] = true;
  71. for (ul v : edge[u]) {
  72. if (!al[v]) {
  73. continue;
  74. }
  75. if (connect(u, v)) {
  76. --cnt;
  77. }
  78. }
  79. }
  80. ans += ull(cnt) * (it->first - nit->first);
  81. }
  82. oss << ans << '\n';
  83. }
  84. std::cout << oss.str();
  85. return 0;
  86. }

B、Blood Pressure Game 6764

官方题解如下:
image.png-178.5kB
image.png-51.3kB

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  5. using ul = std::uint32_t;
  6. using li = std::int32_t;
  7. using ull = std::uint64_t;
  8. using ll = std::int64_t;
  9. ul T;
  10. const ul maxn = 600;
  11. ul n, k;
  12. ul a[maxn + 1];
  13. const ul mod = 1e9 + 7;
  14. ul plus(ul a, ul b)
  15. {
  16. return a + b < mod ? a + b : a + b - mod;
  17. }
  18. ul minus(ul a, ul b)
  19. {
  20. return a < b ? a + mod - b : a - b;
  21. }
  22. ul mul(ul a, ul b)
  23. {
  24. return ull(a) * ull(b) % mod;
  25. }
  26. class counter {
  27. public:
  28. ul len = 0;
  29. ul cnt = 0;
  30. counter()=default;
  31. counter(ul a, ul b): len(a), cnt(b) {}
  32. };
  33. std::vector<counter> f[2][maxn + 1][3];
  34. std::vector<counter> tmp;
  35. int main()
  36. {
  37. std::ios::sync_with_stdio(false);
  38. std::cin.tie(0);
  39. iss.tie(0);
  40. oss.tie(0);
  41. std::getline(std::cin, instr, char(0));
  42. iss.str(instr);
  43. iss >> T;
  44. for (ul Case = 1; Case <= T; ++Case) {
  45. iss >> n >> k;
  46. for (ul i = 1; i <= n; ++i) {
  47. iss >> a[i];
  48. }
  49. std::sort(a + 1, a + n + 1);
  50. for (ul j = 1; j <= n; ++j) {
  51. for (ul t = 0; t <= 2; ++t) {
  52. f[1][j][t].resize(0);
  53. }
  54. }
  55. f[1][4][0] = std::vector<counter>(1, counter(0, 1));
  56. f[1][5][1] = std::vector<counter>(1, counter(0, 2));
  57. for (ul i = 1; i + 1 <= n; ++i) {
  58. for (ul j = 1; j <= i + 1; ++j) {
  59. for (ul t = 0; t <= 2; ++t) {
  60. f[i + 1 & 1][j][t].resize(0);
  61. }
  62. }
  63. for (ul j = 1; j <= i; ++j) {
  64. for (ul t = 0; t <= 2; ++t) {
  65. ul tmp = (j + j - t) * (a[i + 1] - a[i]);
  66. for (const auto& c : f[i & 1][j][t]) {
  67. if (j + 1 > t) {
  68. f[i + 1 & 1][j + 1][t].push_back(counter(c.len + tmp, mul(c.cnt, j + 1 - t)));
  69. }
  70. if (2 > t) {
  71. f[i + 1 & 1][j + 1][t + 1].push_back(counter(c.len + tmp, mul(c.cnt, 2 - t)));
  72. }
  73. if (j > 1) {
  74. f[i + 1 & 1][j - 1][t].push_back(counter(c.len + tmp, mul(c.cnt, j - 1)));
  75. }
  76. if (j + j > t) {
  77. f[i + 1 & 1][j][t].push_back(counter(c.len + tmp, mul(c.cnt, j + j - t)));
  78. }
  79. if (2 > t) {
  80. f[i + 1 & 1][j][t + 1].push_back(counter(c.len + tmp, mul(c.cnt, 2 - t)));
  81. }
  82. }
  83. }
  84. }
  85. for (ul j = 1; j <= i + 1; ++j) {
  86. for (ul t = 0; t <= 2; ++t) {
  87. std::sort(f[i + 1 & 1][j][t].begin(), f[i + 1 & 1][j][t].end(), [](const counter& a, const counter& b){return a.len > b.len;});
  88. tmp.resize(0);
  89. for (const auto& c : f[i + 1 & 1][j][t]) {
  90. if (tmp.empty() || c.len != tmp.back().len) {
  91. if (tmp.size() == k) {
  92. break;
  93. }
  94. tmp.push_back(c);
  95. } else {
  96. tmp.back().cnt = plus(tmp.back().cnt, c.cnt);
  97. }
  98. }
  99. std::swap(tmp, f[i + 1 & 1][j][t]);
  100. }
  101. }
  102. }
  103. for (ul i = 0; i != k; ++i) {
  104. if (i >= f[n & 1][6][2].size()) {
  105. oss << "-1\n";
  106. } else {
  107. oss << f[n & 1][7][2][i].len << ' ' << f[n & 1][8][2][i].cnt << '\n';
  108. }
  109. }
  110. }
  111. std::cout << oss.str();
  112. return 0;
  113. }

C、Count on a Tree II Striking Back 6765

官方题解如下:
image.png-111.9kB
来估计一下到底需要取到多少。姑且假设随机数生成器能做到完全独立(虽然实际做不到,但这是没办法的)。现在设执行了次实验(足够大),故对于个颜色,其颜色权值的最小值在次实验的平均值近似为正态分布,
对于两个符合正态分布的随机变量(不保证独立),,则有如下上界

其中

于是如果取,正确概率至少能大于一半。

然而实际上,取这么大会超时,所以,我只能选择取到,但我不知道怎么证明取到是足够的

  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. std::mt19937 rnd;
  7. ul T;
  8. ul n, m;
  9. ul cnt;
  10. const ul maxn = 5e5;
  11. ul col[maxn + 1];
  12. const ul k = 35;
  13. ul w[maxn + 1][k + 1];
  14. ul head[maxn + 1];
  15. class edge {
  16. public:
  17. ul to = 0;
  18. ul next = 0;
  19. edge()=default;
  20. edge(ul a, ul b): to(a), next(b) {}
  21. };
  22. ul tot;
  23. edge edges[maxn + maxn];
  24. ul bigson[maxn + 1];
  25. ul fa[maxn + 1];
  26. ul size[maxn + 1];
  27. ul depth[maxn + 1];
  28. ul hvhd[maxn + 1];
  29. ul lsiz[maxn + 1];
  30. void search1(ul curr, ul prev)
  31. {
  32. bigson[curr] = 0;
  33. size[curr] = 1;
  34. ul mxsz = 0;
  35. for (ul nextid = head[curr]; nextid; nextid = edges[nextid].next) {
  36. ul next = edges[nextid].to;
  37. if (next == prev) {
  38. continue;
  39. }
  40. search1(next, curr);
  41. size[curr] += size[next];
  42. if (size[next] > mxsz) {
  43. mxsz = size[next];
  44. bigson[curr] = next;
  45. }
  46. }
  47. lsiz[curr] = size[curr];
  48. if (bigson[curr]) {
  49. lsiz[curr] -= size[bigson[curr]];
  50. }
  51. }
  52. void search2(ul curr, ul prev)
  53. {
  54. fa[curr] = prev;
  55. for (ul nextid = head[curr]; nextid; nextid = edges[nextid].next) {
  56. ul next = edges[nextid].to;
  57. if (next == prev) {
  58. continue;
  59. }
  60. if (next == bigson[curr]) {
  61. hvhd[next] = hvhd[curr];
  62. } else {
  63. hvhd[next] = next;
  64. }
  65. depth[next] = depth[curr] + 1;
  66. search2(next, curr);
  67. }
  68. }
  69. ul lson[maxn + 1];
  70. ul rson[maxn + 1];
  71. ul lbound[maxn + 1];
  72. ul rbound[maxn + 1];
  73. ul tree[maxn + 1][k + 1];
  74. const ul inf = ~ul(0);
  75. void query(ul l, ul r, ul curr, ul ret[])
  76. {
  77. if (l <= lbound[curr] && r >= rbound[curr]) {
  78. for (ul i = 1; i <= k; ++i) {
  79. ret[i] = std::min(ret[i], tree[curr][i]);
  80. }
  81. return;
  82. }
  83. if (l <= depth[curr] && r >= depth[curr]) {
  84. for (ul i = 1; i <= k; ++i) {
  85. ret[i] = std::min(ret[i], w[col[curr]][i]);
  86. }
  87. }
  88. if (l < depth[curr] && lson[curr]) {
  89. query(l, r, lson[curr], ret);
  90. }
  91. if (r > depth[curr] && rson[curr]) {
  92. query(l, r, rson[curr], ret);
  93. }
  94. }
  95. void build(ul curr)
  96. {
  97. std::memcpy(tree[curr] + 1, w[col[curr]] + 1, sizeof(ul) * k);
  98. if (lson[curr]) {
  99. build(lson[curr]);
  100. for (ul i = 1; i <= k; ++i) {
  101. tree[curr][i] = std::min(tree[curr][i], tree[lson[curr]][i]);
  102. }
  103. }
  104. if (rson[curr]) {
  105. build(rson[curr]);
  106. for (ul i = 1; i <= k; ++i) {
  107. tree[curr][i] = std::min(tree[curr][i], tree[rson[curr]][i]);
  108. }
  109. }
  110. }
  111. void change(ul pos, ul curr, ul y)
  112. {
  113. if (depth[curr] > pos) {
  114. change(pos, lson[curr], y);
  115. } else if (depth[curr] < pos) {
  116. change(pos, rson[curr], y);
  117. }
  118. std::memcpy(tree[curr] + 1, w[col[curr]] + 1, sizeof(ul) * k);
  119. if (lson[curr]) {
  120. for (ul i = 1; i <= k; ++i) {
  121. tree[curr][i] = std::min(tree[curr][i], tree[lson[curr]][i]);
  122. }
  123. }
  124. if (rson[curr]) {
  125. for (ul i = 1; i <= k; ++i) {
  126. tree[curr][i] = std::min(tree[curr][i], tree[rson[curr]][i]);
  127. }
  128. }
  129. }
  130. ul root[maxn + 1];
  131. ull query(ul u, ul v)
  132. {
  133. static ul ret[k + 1];
  134. for (ul i = 1; i <= k; ++i) {
  135. ret[i] = inf;
  136. }
  137. while (true) {
  138. if (hvhd[u] == hvhd[v]) {
  139. query(std::min(depth[u], depth[v]), std::max(depth[u], depth[v]), root[hvhd[u]], ret);
  140. break;
  141. }
  142. if (depth[hvhd[u]] > depth[hvhd[v]]) {
  143. std::swap(u, v);
  144. }
  145. query(depth[hvhd[v]], depth[v], root[hvhd[v]], ret);
  146. v = fa[hvhd[v]];
  147. }
  148. ull sret = 0;
  149. for (ul i = 1; i <= k; ++i) {
  150. sret += ret[i];
  151. }
  152. return sret;
  153. }
  154. ul node[maxn + 1];
  155. ul deal(ul l, ul r)
  156. {
  157. if (l == r + 1) {
  158. return 0;
  159. }
  160. ul sum = 0;
  161. for (ul i = l; i <= r; ++i) {
  162. sum += lsiz[node[i]];
  163. }
  164. ul sum2 = 0;
  165. for (ul i = l; i <= r; ++i) {
  166. sum2 += lsiz[node[i]];
  167. if (sum2 + sum2 >= sum) {
  168. lson[node[i]] = deal(l, i - 1);
  169. rson[node[i]] = deal(i + 1, r);
  170. lbound[node[i]] = l;
  171. rbound[node[i]] = r;
  172. return node[i];
  173. }
  174. }
  175. }
  176. ul prevtime = 0;
  177. double gettime()
  178. {
  179. ul tmp = std::clock();
  180. double ret = double(tmp - prevtime) / CLOCKS_PER_SEC;
  181. prevtime = tmp;
  182. return ret;
  183. }
  184. int main()
  185. {
  186. rnd.seed(std::time(0));
  187. std::scanf("%u", &T);
  188. for (ul Case = 1; Case <= T; ++Case) {
  189. std::scanf("%u%u", &n, &m);
  190. for (ul i = 1; i <= n; ++i) {
  191. for (ul j = 1; j <= k; ++j) {
  192. w[i][j] = rnd();
  193. }
  194. }
  195. tot = 0;
  196. for (ul i = 1; i <= n; ++i) {
  197. std::scanf("%u", &col[i]);
  198. head[i] = 0;
  199. }
  200. for (ul i = 1; i <= n - 1; ++i) {
  201. ul u, v;
  202. std::scanf("%u%u", &u, &v);
  203. ++tot;
  204. edges[tot].to = v;
  205. edges[tot].next = head[u];
  206. head[u] = tot;
  207. ++tot;
  208. edges[tot].to = u;
  209. edges[tot].next = head[v];
  210. head[v] = tot;
  211. }
  212. search1(1, 0);
  213. hvhd[1] = 1;
  214. depth[1] = 0;
  215. search2(1, 0);
  216. for (ul i = 1; i <= n; ++i) {
  217. if (hvhd[i] != i) {
  218. continue;
  219. }
  220. ul md = 0;
  221. for (ul j = i; j; j = bigson[j]) {
  222. node[depth[j]] = j;
  223. md = depth[j];
  224. }
  225. root[i] = deal(depth[i], md);
  226. }
  227. for (ul i = 1; i <= n; ++i) {
  228. if (i == hvhd[i]) {
  229. build(root[i]);
  230. }
  231. }
  232. cnt = 0;
  233. for (ul i = 1; i <= m; ++i) {
  234. ul q;
  235. std::scanf("%u", &q);
  236. if (q == 1) {
  237. ul x, y;
  238. std::scanf("%u%u", &x, &y);
  239. x ^= cnt;
  240. y ^= cnt;
  241. col[x] = y;
  242. change(depth[x], root[hvhd[x]], y);
  243. } else {
  244. ul a, b, c, d;
  245. std::scanf("%u%u%u%u", &a, &b, &c, &d);
  246. a ^= cnt;
  247. b ^= cnt;
  248. c ^= cnt;
  249. d ^= cnt;
  250. if (query(a, b) < query(c, d)) {
  251. ++cnt;
  252. std::printf("Yes\n");
  253. } else {
  254. std::printf("No\n");
  255. }
  256. }
  257. }
  258. }
  259. prevtime = 0;
  260. return 0;
  261. }

D、Diamond Rush 6766

官方题解如下:
image.png-213.8kB

  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 pulul = std::pair<ul, ul>;
  7. ul prevtime = 0;
  8. double gettime()
  9. {
  10. ul tmp = std::clock();
  11. double ret = double(tmp - prevtime) / CLOCKS_PER_SEC;
  12. prevtime = tmp;
  13. return ret;
  14. }
  15. std::mt19937 rnd;
  16. const ul mod = 1e9 + 7;
  17. ul plus(ul a, ul b)
  18. {
  19. return a + b < mod ? a + b : a + b - mod;
  20. }
  21. ul minus(ul a, ul b)
  22. {
  23. return a < b ? a + mod - b : a - b;
  24. }
  25. ul mul(ul a, ul b)
  26. {
  27. return ull(a) * ull(b) % mod;
  28. }
  29. const ul maxn = 400;
  30. ul T;
  31. ul a[maxn + 1][maxn + 1];
  32. ul n;
  33. ul q;
  34. ul ans11[maxn + 1][maxn + 1];
  35. ul ansnn[maxn + 1][maxn + 1];
  36. pulul f[maxn + 1][maxn + 1];
  37. pulul fr[maxn + 1][maxn + 1];
  38. pulul fl[maxn + 1][maxn + 1];
  39. class node {
  40. public:
  41. ul hash = 0;
  42. ul val = 0;
  43. ul cnt = 0;
  44. ul lson = 0;
  45. ul rson = 0;
  46. node()=default;
  47. };
  48. ul tot = 0;
  49. node tree[ul(1e7)];
  50. ul basepow[maxn * maxn + 1];
  51. ul n2pow[maxn + maxn + 1];
  52. void insert(ul pos, ul& root, ul l, ul r)
  53. {
  54. ++tot;
  55. tree[tot] = tree[root];
  56. root = tot;
  57. tree[root].hash = plus(tree[root].hash, basepow[pos]);
  58. tree[root].val = plus(tree[root].val, n2pow[pos]);
  59. ++tree[root].cnt;
  60. if (l == r) {
  61. return;
  62. }
  63. ul mid = l + r >> 1;
  64. if (pos <= mid) {
  65. insert(pos, tree[root].lson, l, mid);
  66. } else {
  67. insert(pos, tree[root].rson, mid + 1, r);
  68. }
  69. }
  70. bool compare(ul x, ul y, ul l, ul r)
  71. {
  72. if (l == r) {
  73. return tree[x].cnt < tree[y].cnt;
  74. }
  75. if (tree[tree[x].rson].hash != tree[tree[y].rson].hash) {
  76. return compare(tree[x].rson, tree[y].rson, (l + r >> 1) + 1, r);
  77. } else {
  78. return compare(tree[x].lson, tree[y].lson, l, l + r >> 1);
  79. }
  80. }
  81. bool compare(ul x1, ul x2, ul y1, ul y2, ul l, ul r)
  82. {
  83. if (l == r) {
  84. return tree[x1].cnt + tree[x2].cnt < tree[y1].cnt + tree[y2].cnt;
  85. }
  86. if (plus(tree[tree[x1].rson].hash, tree[tree[x2].rson].hash) != plus(tree[tree[y1].rson].hash, tree[tree[y2].rson].hash)) {
  87. return compare(tree[x1].rson, tree[x2].rson, tree[y1].rson, tree[y2].rson, (l + r >> 1) + 1, r);
  88. } else {
  89. return compare(tree[x1].lson, tree[x2].lson, tree[y1].lson, tree[y2].lson, l, l + r >> 1);
  90. }
  91. }
  92. int main()
  93. {
  94. rnd.seed(std::time(0));
  95. std::scanf("%u", &T);
  96. for (ul Case = 1; Case <= T; ++Case) {
  97. tot = 0;
  98. std::scanf("%u%u", &n, &q);
  99. ul base = rnd() % mod;
  100. basepow[0] = 1;
  101. n2pow[0] = 1;
  102. for (ul i = 1; i <= n * n; ++i) {
  103. basepow[i] = mul(basepow[i - 1], base);
  104. n2pow[i] = mul(n2pow[i - 1], n * n);
  105. }
  106. for (ul i = 1; i <= n; ++i) {
  107. for (ul j = 1; j <= n; ++j) {
  108. std::scanf("%u", &a[i][j]);
  109. }
  110. }
  111. for (ul i = 1; i <= n; ++i) {
  112. for (ul j = 1; j <= n; ++j) {
  113. if (i == 1) {
  114. if (j == 1) {
  115. ans11[i][j] = 0;
  116. } else {
  117. ans11[i][j] = ans11[i][j - 1];
  118. }
  119. } else {
  120. if (j == 1) {
  121. ans11[i][j] = ans11[i - 1][j];
  122. } else {
  123. ans11[i][j] = compare(ans11[i - 1][j], ans11[i][j - 1], 1, n * n) ? ans11[i][j - 1] : ans11[i - 1][j];
  124. }
  125. }
  126. insert(a[i][j], ans11[i][j], 1, n * n);
  127. }
  128. }
  129. for (ul i = n; i >= 1; --i) {
  130. for (ul j = n; j >= 1; --j) {
  131. if (i == n) {
  132. if (j == n) {
  133. ansnn[i][j] = 0;
  134. } else {
  135. ansnn[i][j] = ansnn[i][j + 1];
  136. }
  137. } else {
  138. if (j == n) {
  139. ansnn[i][j] = ansnn[i + 1][j];
  140. } else {
  141. ansnn[i][j] = compare(ansnn[i + 1][j], ansnn[i][j + 1], 1, n * n) ? ansnn[i][j + 1] : ansnn[i + 1][j];
  142. }
  143. }
  144. f[i][j] = pulul(ans11[i][j], ansnn[i][j]);
  145. insert(a[i][j], ansnn[i][j], 1, n * n);
  146. fl[i][j] = f[i][j];
  147. if (i != n && j != 1) {
  148. fl[i][j] = compare(fl[i][j].first, fl[i][j].second, fl[i + 1][j - 1].first, fl[i + 1][j - 1].second, 1, n * n) ? fl[i + 1][j - 1] : fl[i][j];
  149. }
  150. }
  151. }
  152. for (ul i = 1; i <= n; ++i) {
  153. for (ul j = 1; j <= n; ++j) {
  154. fr[i][j] = f[i][j];
  155. if (i != 1 && j != n) {
  156. fr[i][j] = compare(fr[i][j].first, fr[i][j].second, fr[i - 1][j + 1].first, fr[i - 1][j + 1].second, 1, n * n) ? fr[i - 1][j + 1] : fr[i][j];
  157. }
  158. }
  159. }
  160. for (ul i = 1; i <= q; ++i) {
  161. ul xl, xr, yl, yr;
  162. std::scanf("%u%u%u%u", &xl, &xr, &yl, &yr);
  163. pulul tmp(0, 0);
  164. if (xr != n && yl != 1) {
  165. tmp = compare(tmp.first, tmp.second, fl[xr + 1][yl - 1].first, fl[xr + 1][yl - 1].second, 1, n * n) ? fl[xr + 1][yl - 1] : tmp;
  166. }
  167. if (xl != 1 && yr != n) {
  168. tmp = compare(tmp.first, tmp.second, fr[xl - 1][yr + 1].first, fr[xl - 1][yr + 1].second, 1, n * n) ? fr[xl - 1][yr + 1] : tmp;
  169. }
  170. std::printf("%u\n", plus(tree[tmp.first].val, tree[tmp.second].val));
  171. }
  172. }
  173. return 0;
  174. }

E、New Equipments 6767

简单题

  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 T;
  7. ul n;
  8. li m;
  9. const ul maxn = 50;
  10. const li liinf = (li(1) << 31) - 1;
  11. const ll llinf = (ll(1) << 63) - 1;
  12. class achieve_t {
  13. public:
  14. ul to = 0;
  15. ll sigma = 0;
  16. achieve_t()=default;
  17. achieve_t(ul to, ll sigma): to(to), sigma(sigma) {}
  18. };
  19. bool operator<(const achieve_t& a, const achieve_t& b)
  20. {
  21. return a.sigma > b.sigma;
  22. }
  23. class mcmf {
  24. public:
  25. class edge_t {
  26. public:
  27. ul to = 0;
  28. li cap = 0;
  29. ll cost = 0;
  30. edge_t()=default;
  31. edge_t(ul to, li cap, ll cost): to(to), cap(cap), cost(cost) {}
  32. };
  33. class node_t {
  34. public:
  35. ll pi;
  36. ll sigma;
  37. ul p;
  38. li a;
  39. ul vis;
  40. std::vector<ul> edge;
  41. };
  42. node_t node[maxn + maxn * maxn + 2];
  43. edge_t edge[maxn * maxn + maxn + maxn * maxn << 1];
  44. std::priority_queue<achieve_t> heap;
  45. std::queue<ul> queue;
  46. ul tim = 0;
  47. ul n, m;
  48. void init(ul n) {
  49. this->n = n;
  50. for (ul i = 0; i != n; ++i) {
  51. node[i].edge.resize(0);
  52. node[i].pi = 0;
  53. }
  54. m = 0;
  55. }
  56. void addedge(ul from, ul to, li cap, ll cost) {
  57. edge[m] = edge_t(to, cap, cost);
  58. ++m;
  59. edge[m] = edge_t(from, 0, -cost);
  60. ++m;
  61. node[from].edge.push_back(m - 2);
  62. node[to].edge.push_back(m - 1);
  63. }
  64. bool dikstra(ul s, ul t, li& flow, ll& cost) {
  65. for (ul i = 0; i != n; ++i) {
  66. node[i].sigma = llinf;
  67. }
  68. while (heap.size()) {
  69. heap.pop();
  70. }
  71. heap.push(achieve_t(s, 0));
  72. node[s].sigma = 0;
  73. while (heap.size()) {
  74. auto ach = heap.top();
  75. heap.pop();
  76. if (ach.sigma > node[ach.to].sigma) {
  77. continue;
  78. }
  79. for (ul i : node[ach.to].edge) {
  80. edge_t& e = edge[i];
  81. if (e.cap > 0 && node[e.to].sigma > ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi) {
  82. node[e.to].sigma = ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi;
  83. heap.push(achieve_t(e.to, ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi));
  84. }
  85. }
  86. }
  87. if (node[t].sigma == llinf) {
  88. return false;
  89. }
  90. while (queue.size()) {
  91. queue.pop();
  92. }
  93. ++tim;
  94. node[s].p = -1;
  95. node[s].a = liinf;
  96. queue.push(s);
  97. node[s].vis = tim;
  98. while (queue.size()) {
  99. ul curr = queue.front();
  100. queue.pop();
  101. for (ul i : node[curr].edge) {
  102. edge_t& e = edge[i];
  103. ul nex = e.to;
  104. if (e.cap > 0 && node[nex].vis != tim && node[nex].sigma == node[curr].sigma + e.cost + node[curr].pi - node[nex].pi) {
  105. node[nex].p = i;
  106. node[nex].a = std::min(node[curr].a, e.cap);
  107. node[nex].vis = tim;
  108. queue.push(nex);
  109. }
  110. }
  111. }
  112. flow += node[t].a;
  113. cost += ll(node[t].sigma + node[t].pi - node[s].pi) * node[t].a;
  114. ul u = t;
  115. while (u != s) {
  116. edge[node[u].p].cap -= node[t].a;
  117. edge[node[u].p ^ 1].cap += node[t].a;
  118. u = edge[node[u].p ^ 1].to;
  119. }
  120. for (ul i = 0; i != n; ++i) {
  121. node[i].pi = node[i].sigma == llinf ? llinf : node[i].pi + node[i].sigma;
  122. }
  123. return true;
  124. }
  125. ll mincost(ul s, ul t) {
  126. li flow = 0;
  127. ll cost = 0;
  128. while (dikstra(s, t, flow, cost));
  129. return cost;
  130. }
  131. };
  132. mcmf graph;
  133. ll a[maxn + 1], b[maxn + 1], c[maxn + 1];
  134. std::vector<li> need[maxn + 1];
  135. std::vector<ul> al;
  136. using pulull = std::pair<ul, ull>;
  137. std::vector<pulull> set;
  138. std::map<ul, ul> id;
  139. int main()
  140. {
  141. std::scanf("%u", &T);
  142. for (ul Case = 1; Case <= T; ++Case) {
  143. std::scanf("%u%d", &n, &m);
  144. al.resize(0);
  145. for (ul i = 1; i <= n; ++i) {
  146. std::scanf("%lld%lld%lld", &a[i], &b[i], &c[i]);
  147. need[i].resize(0);
  148. ll tmp = -2 * a[i];
  149. if (b[i] > tmp) {
  150. for (ul j = 1; j <= m && j <= n; ++j) {
  151. need[i].push_back(j);
  152. al.push_back(j);
  153. }
  154. } else if (b[i] < m * tmp) {
  155. for (ul j = m; m - j + 1 <= n && j >= 1; --j) {
  156. need[i].push_back(j);
  157. al.push_back(j);
  158. }
  159. } else {
  160. set.resize(0);
  161. for (ll j = b[i] / tmp - 100; j <= b[i] / tmp + 100; ++j) {
  162. if (j < 1) {
  163. continue;
  164. }
  165. if (j > m) {
  166. continue;
  167. }
  168. set.push_back(pulull(j, a[i] * j * j + b[i] * j + c[i]));
  169. }
  170. std::sort(set.begin(), set.end(), [](const pulull& a, const pulull& b){return a.second < b.second;});
  171. set.resize(std::min(ul(n), ul(m)));
  172. for (auto p : set) {
  173. need[i].push_back(p.first);
  174. al.push_back(p.first);
  175. }
  176. }
  177. }
  178. std::sort(al.begin(), al.end());
  179. al.resize(std::unique(al.begin(), al.end()) - al.begin());
  180. ul tim = n;
  181. for (auto a : al) {
  182. ++tim;
  183. id[a] = tim;
  184. }
  185. ++tim;
  186. graph.init(tim + 1);
  187. for (ul i = 1; i <= n; ++i) {
  188. graph.addedge(0, i, 1, 0);
  189. for (ll j : need[i]) {
  190. graph.addedge(i, id[j], 1, a[i] * j * j + b[i] * j + c[i]);
  191. }
  192. }
  193. for (auto a : al) {
  194. graph.addedge(id[a], tim, 1, 0);
  195. }
  196. li flow = 0;
  197. ll cost = 0;
  198. for (li i = 1; i <= n; ++i) {
  199. if (i != 1) {
  200. std::putchar(' ');
  201. }
  202. while (i > flow) {
  203. graph.dikstra(0, tim, flow, cost);
  204. }
  205. std::printf("%lld", cost);
  206. }
  207. std::putchar('\n');
  208. }
  209. return 0;
  210. }

F、The Oculus 6768

简单题

  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. ul T;
  8. const ul maxn = 1e6;
  9. ull fib[maxn + maxn + 2];
  10. int main()
  11. {
  12. fib[0] = fib[1] = 1;
  13. for (ul i = 2; i <= maxn + maxn + 1; ++i) {
  14. fib[i] = fib[i - 1] + fib[i - 2];
  15. }
  16. std::scanf("%u", &T);
  17. for (ul Case = 1; Case <= T; ++Case) {
  18. ul al, bl, cl;
  19. ull a = 0, b = 0, c = 0;
  20. ul ai, bi, ci;
  21. std::scanf("%u", &al);
  22. for (ul i = 1; i <= al; ++i) {
  23. std::scanf("%u", &ai);
  24. if (ai) {
  25. a += fib[i];
  26. }
  27. }
  28. std::scanf("%u", &bl);
  29. for (ul i = 1; i <= bl; ++i) {
  30. std::scanf("%u", &bi);
  31. if (bi) {
  32. b += fib[i];
  33. }
  34. }
  35. std::scanf("%u", &cl);
  36. for (ul i = 1; i <= cl; ++i) {
  37. std::scanf("%u", &ci);
  38. if (ci) {
  39. c += fib[i];
  40. }
  41. }
  42. ull t = a * b - c;
  43. for (ul i = 1; ; ++i) {
  44. if (fib[i] == t) {
  45. std::printf("%u\n", i);
  46. break;
  47. }
  48. }
  49. }
  50. return 0;
  51. }

G、In Search of Gold 6769

官方题解如下:
image.png-124.9kB

  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 T;
  7. const ul maxn = 2e4;
  8. const ul maxk = 20;
  9. ul n, k;
  10. class edge {
  11. public:
  12. ul a = 0;
  13. ul b = 0;
  14. ul to = 0;
  15. edge()=default;
  16. edge(ul x, ul y, ul z): to(x), a(y), b(z) {}
  17. };
  18. std::vector<edge> edges[maxn + 1];
  19. ull f[maxn + 1][maxk + 1];
  20. ull tmpf[maxk + 1];
  21. ull initf[maxk + 1];
  22. const ull inf = 2e13;
  23. ull bound;
  24. ul search(ul curr, ul prev)
  25. {
  26. std::memcpy(f[curr], initf, sizeof(ull) * (k + 1));
  27. f[curr][0] = 0;
  28. ul currcnt = 0;
  29. for (const auto& e : edges[curr]) {
  30. ul next = e.to;
  31. if (next == prev) {
  32. continue;
  33. }
  34. ul nextcnt = search(next, curr);
  35. std::memcpy(tmpf, initf, sizeof(ull) * (k + 1));
  36. for (ul x = 0; x <= k && x <= currcnt; ++x) {
  37. if (f[curr][x] == inf) {
  38. continue;
  39. }
  40. for (ul y = 0; x + y <= k && y <= nextcnt; ++y) {
  41. if (f[next][y] == inf) {
  42. continue;
  43. }
  44. if (f[curr][x] + f[next][y] + e.b <= bound) {
  45. tmpf[x + y] = std::min(tmpf[x + y], std::max(f[curr][x], f[next][y] + e.b));
  46. }
  47. if (x + y != k && f[curr][x] + f[next][y] + e.a <= bound) {
  48. tmpf[x + y + 1] = std::min(tmpf[x + y + 1], std::max(f[curr][x], f[next][y] + e.a));
  49. }
  50. }
  51. }
  52. std::memcpy(f[curr], tmpf, sizeof(ull) * (k + 1));
  53. currcnt += nextcnt + 1;
  54. }
  55. return currcnt;
  56. }
  57. int main()
  58. {
  59. for (ul i = 0; i <= maxk; ++i) {
  60. initf[i] = inf;
  61. }
  62. std::scanf("%u", &T);
  63. for (ul Case = 1; Case <= T; ++Case) {
  64. std::scanf("%u%u", &n, &k);
  65. for (ul i = 1; i <= n; ++i) {
  66. edges[i].resize(0);
  67. }
  68. for (ul i = 1; i <= n - 1; ++i) {
  69. ul u, v, a, b;
  70. std::scanf("%u%u%u%u", &u, &v, &a, &b);
  71. edges[u].push_back(edge(v, a, b));
  72. edges[v].push_back(edge(u, a, b));
  73. }
  74. ull l = n - 2, r = 2e13;
  75. while (l + 1 != r) {
  76. bound = l + r >> 1;
  77. search(1, 0);
  78. if (f[1][k] == inf) {
  79. l = bound;
  80. } else {
  81. r = bound;
  82. }
  83. }
  84. std::printf("%llu\n", r);
  85. }
  86. return 0;
  87. }

H、Dynamic Convex Hull 6770

官方题解如下:
image.png-211.5kB
image.png-8.9kB

  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 T;
  7. const ul maxn = 1e5;
  8. const ul maxm = 1e5;
  9. ul n, m;
  10. ul a[maxn + maxm + 1];
  11. ull b[maxn + maxm + 1];
  12. ul l[maxn + maxm + 1];
  13. bool erased[maxn + maxm + 1];
  14. ull ans[maxm + 1];
  15. ul tot;
  16. ul x[maxm + 1];
  17. const ul sz = 1 << 17;
  18. std::vector<ul> tos[sz << 1];
  19. std::vector<ul> froms[sz << 1];
  20. void insert(ul l, ul r, ul v)
  21. {
  22. for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {
  23. if (~l & 1) {
  24. froms[l ^ 1].push_back(v);
  25. }
  26. if (r & 1) {
  27. froms[r ^ 1].push_back(v);
  28. }
  29. }
  30. }
  31. void insert(ul pos, ul v)
  32. {
  33. for (pos |= sz; pos; pos >>= 1) {
  34. tos[pos].push_back(v);
  35. }
  36. }
  37. ull f(ull x, ull a, ull b)
  38. {
  39. return (x - a) * (x - a) * (x - a) * (x - a) + b;
  40. }
  41. const ull inf = 9e18;
  42. void deal(ul xl, ul xr, ul fl, ul fr, ul nid)
  43. {
  44. if (xl == xr + 1) {
  45. return;
  46. }
  47. ul mid = xl + xr >> 1;
  48. ull tmpans = inf;
  49. ul lbound, rbound;
  50. for (ul i = fl; i <= fr; ++i) {
  51. ull cans = f(x[tos[nid][mid]], a[froms[nid][i]], b[froms[nid][i]]);
  52. if (tmpans > cans) {
  53. tmpans = cans;
  54. lbound = i;
  55. rbound = i;
  56. } else if (tmpans == cans) {
  57. rbound = i;
  58. }
  59. }
  60. deal(xl, mid - 1, fl, lbound, nid);
  61. deal(mid + 1, xr, rbound, fr, nid);
  62. ans[tos[nid][mid]] = std::min(ans[tos[nid][mid]], tmpans);
  63. }
  64. int main()
  65. {
  66. std::scanf("%u", &T);
  67. for (ul Case = 1; Case <= T; ++Case) {
  68. for (ul i = 0; i != sz + sz; ++i) {
  69. tos[i].resize(0);
  70. froms[i].resize(0);
  71. }
  72. std::scanf("%u%u", &n, &m);
  73. tot = n;
  74. for (ul i = 1; i <= n; ++i) {
  75. std::scanf("%u%llu", &a[i], &b[i]);
  76. l[i] = 1;
  77. erased[i] = false;
  78. }
  79. for (ul i = 1; i <= m; ++i) {
  80. x[i] = 0;
  81. ul k;
  82. std::scanf("%u", &k);
  83. if (k == 1) {
  84. ++tot;
  85. std::scanf("%u%llu", &a[tot], &b[tot]);
  86. erased[tot] = false;
  87. l[tot] = i;
  88. } else if (k == 2) {
  89. ul t;
  90. std::scanf("%u", &t);
  91. erased[t] = true;
  92. insert(l[t], i, t);
  93. } else if (k == 3) {
  94. ans[i] = inf;
  95. std::scanf("%u", &x[i]);
  96. insert(i, i);
  97. }
  98. }
  99. for (ul i = 1; i <= tot; ++i) {
  100. if (!erased[i]) {
  101. insert(l[i], m, i);
  102. }
  103. }
  104. for (ul i = 1; i != sz + sz; ++i) {
  105. if (froms[i].size() && tos[i].size()) {
  106. std::sort(froms[i].begin(), froms[i].end(), [](ul s, ul t){return a[s] < a[t];});
  107. std::sort(tos[i].begin(), tos[i].end(), [](ul s, ul t){return x[s] < x[t];});
  108. deal(0, tos[i].size() - 1, 0, froms[i].size() - 1, i);
  109. }
  110. }
  111. for (ul i = 1; i <= m; ++i) {
  112. if (x[i]) {
  113. if (ans[i] == inf) {
  114. std::printf("-1\n");
  115. } else {
  116. std::printf("%llu\n", ans[i]);
  117. }
  118. }
  119. }
  120. }
  121. return 0;
  122. }

I、It's All Squares 6771

暴力

  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 T;
  7. const ul maxn = 400;
  8. const ul maxm = 400;
  9. ul n, m, q;
  10. ul w[maxn + 1][maxm + 1];
  11. std::vector<ul> stack;
  12. std::vector<bool> instack(maxn * maxm + 1, false);
  13. std::vector<ul> bounds[maxn + 1];
  14. char str[4000002];
  15. int main()
  16. {
  17. std::scanf("%u", &T);
  18. for (ul Case = 1; Case <= T; ++Case) {
  19. std::scanf("%u%u%u", &n, &m, &q);
  20. for (ul i = 1; i <= n; ++i) {
  21. for (ul j = 1; j <= m; ++j) {
  22. std::scanf("%u", &w[i][j]);
  23. }
  24. }
  25. for (ul i = 1; i <= q; ++i) {
  26. ul x, y;
  27. std::scanf("%u%u%s", &x, &y, str + 1);
  28. ul mnx = x, mxx = x;
  29. for (ul i = 1; str[i]; ++i) {
  30. if (str[i] == 'L') {
  31. bounds[x].push_back(y);
  32. --x;
  33. } else if (str[i] == 'R') {
  34. ++x;
  35. bounds[x].push_back(y);
  36. } else if (str[i] == 'D') {
  37. --y;
  38. } else if (str[i] == 'U') {
  39. ++y;
  40. }
  41. mnx = std::min(mnx, x);
  42. mxx = std::max(mxx, x);
  43. }
  44. for (ul x = mnx + 1; x <= mxx; ++x) {
  45. std::sort(bounds[x].begin(), bounds[x].end());
  46. for (ul i = 0; i != bounds[x].size(); i += 2) {
  47. for (ul y = bounds[x][i] + 1; y <= bounds[x][i + 1]; ++y) {
  48. if (!instack[w[x][y]]) {
  49. instack[w[x][y]] = true;
  50. stack.push_back(w[x][y]);
  51. }
  52. }
  53. }
  54. bounds[x].resize(0);
  55. }
  56. std::printf("%u\n", ul(stack.size()));
  57. for (ul k : stack) {
  58. instack[k] = false;
  59. }
  60. stack.resize(0);
  61. }
  62. }
  63. return 0;
  64. }

J、Lead of Wisdom 6772

暴力

  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 T;
  7. const ul maxn = 50;
  8. const ul maxk = 50;
  9. ul n, k;
  10. class eq {
  11. public:
  12. ul a = 0;
  13. ul b = 0;
  14. ul c = 0;
  15. ul d = 0;
  16. eq()=default;
  17. };
  18. std::vector<eq> eqs[maxk + 1];
  19. ull ans = 0;
  20. ul a = 100, b = 100, c = 100, d = 100;
  21. void search(ul curr)
  22. {
  23. if (curr == k + 1) {
  24. ans = std::max(ans, ull(a) * ull(b) * ull(c) * ull(d));
  25. return;
  26. }
  27. if (eqs[curr].size() == 0) {
  28. search(curr + 1);
  29. return;
  30. }
  31. for (const auto& e : eqs[curr]) {
  32. a += e.a;
  33. b += e.b;
  34. c += e.c;
  35. d += e.d;
  36. search(curr + 1);
  37. a -= e.a;
  38. b -= e.b;
  39. c -= e.c;
  40. d -= e.d;
  41. }
  42. }
  43. int main()
  44. {
  45. std::scanf("%u", &T);
  46. for (ul Case = 1; Case <= T; ++Case) {
  47. std::scanf("%u%u", &n, &k);
  48. for (ul i = 1; i <= k; ++i) {
  49. eqs[i].resize(0);
  50. }
  51. for (ul i = 1; i <= n; ++i) {
  52. ul t;
  53. std::scanf("%u", &t);
  54. eqs[t].push_back(eq());
  55. std::scanf("%u%u%u%u", &eqs[t].back().a, &eqs[t].back().b, &eqs[t].back().c, &eqs[t].back().d);
  56. }
  57. std::sort(eqs + 1, eqs + k + 1, [](const std::vector<eq>& a, const std::vector<eq>& b){return a.size() < b.size();});
  58. ans = 0;
  59. search(1);
  60. std::printf("%llu\n", ans);
  61. }
  62. return 0;
  63. }

L、String Distance 6774

代码中dp[x][y]表示的公共子序列要长达,则该公共子序列在中末尾下标最小是多少。
right[i][c]表示中第一个为的字符的下标。
ans[i][y]表示的公共子序列要长达,则该公共子序列在中末尾下标最小是多少。

  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 T;
  7. ul n, m, q;
  8. const ul maxn = 1e5;
  9. const ul maxm = 20;
  10. char a[maxn + 1];
  11. char b[maxm + 1];
  12. ul dp[maxm + 1][maxm + 1];
  13. ul right[maxn + 2][26];
  14. ul ans[maxn + 1][maxm + 1];
  15. int main()
  16. {
  17. std::scanf("%u", &T);
  18. for (ul Case = 1; Case <= T; ++Case) {
  19. std::scanf("%s%s", a + 1, b + 1);
  20. n = std::strlen(a + 1);
  21. m = std::strlen(b + 1);
  22. for (ul i = 0; i != 26; ++i) {
  23. right[n + 1][i] = n + 1;
  24. }
  25. for (ul i = n; i; --i) {
  26. std::memcpy(right[i], right[i + 1], sizeof(ul) * 26);
  27. right[i][a[i] - 'a'] = i;
  28. }
  29. for (ul i = 1; i <= n; ++i) {
  30. for (ul x = 0; x <= m; ++x) {
  31. dp[x][0] = i - 1;
  32. for (ul y = 1; y <= x; ++y) {
  33. if (x == y) {
  34. if (dp[x - 1][y - 1] == n + 1) {
  35. dp[x][y] = n + 1;
  36. } else {
  37. dp[x][y] = right[dp[x - 1][y - 1] + 1][b[x] - 'a'];
  38. }
  39. } else {
  40. dp[x][y] = dp[x - 1][y];
  41. if (dp[x - 1][y - 1] != n + 1) {
  42. dp[x][y] = std::min(dp[x][y], right[dp[x - 1][y - 1] + 1][b[x] - 'a']);
  43. }
  44. }
  45. }
  46. }
  47. for (ul x = 0; x <= m; ++x) {
  48. ans[i][x] = dp[m][x];
  49. }
  50. }
  51. std::scanf("%u", &q);
  52. for (ul i = 1; i <= q; ++i) {
  53. ul l, r;
  54. std::scanf("%u%u", &l, &r);
  55. for (ul i = m; ~i; --i) {
  56. if (ans[l][i] <= r) {
  57. std::printf("%u\n", r - l + 1 + m - i - i);
  58. break;
  59. }
  60. }
  61. }
  62. }
  63. return 0;
  64. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注