[关闭]
@qq290637843 2020-12-21T14:23:30.000000Z 字数 21363 阅读 291

2020杭电第三场

A、Tokitsukaze, CSL and Palindrome Game 6791

先考虑对一个字符串,要出现的期望步数问题。将第一次出现时,的长度记为随机变量
,设。于是显然,期望值等于
现在考虑“的长为的前缀中没有出现,而这个子串正好是”这一事件。其概率显然为。现在考虑在此中,第一次出现的位置的尾部的下标。于是必定满足(将记为),故上述引号中事件的概率还可以描述为:

于是
于是
于是

根据以上结论,直接在回文树上比较即可。

  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. using uss = std::uint8_t;
  10. const ul maxn = 1e5;
  11. class pam_t {
  12. public:
  13. ul las;
  14. class node {
  15. public:
  16. ul ch[26];
  17. ul len = 0;
  18. ul fa = 0;
  19. node()=default;
  20. node(ul a, ul b): len(a), fa(b) {
  21. std::memset(ch, 0, sizeof(ch));
  22. }
  23. };
  24. std::vector<node> st = std::vector<node>(maxn + 2);
  25. std::vector<uss> str = std::vector<uss>(maxn + 1);
  26. ul newnode(ul len, ul fail = 0) {
  27. st.push_back(node(len, fail));
  28. return st.size() - 1;
  29. }
  30. ul getfail(ul x, ul n) {
  31. while (str[n - st[x].len - 1] != str[n]) {
  32. x = st[x].fa;
  33. }
  34. return x;
  35. }
  36. bool add(ul c) {
  37. ul i = str.size();
  38. str.push_back(c);
  39. ul cur = getfail(las, i);
  40. bool flag = false;
  41. if (!st[cur].ch[c]) {
  42. ul nw = newnode(st[cur].len + 2, st[getfail(st[cur].fa, i)].ch[c]);
  43. st[cur].ch[c] = nw;
  44. flag = true;
  45. }
  46. las = st[cur].ch[c];
  47. return flag;
  48. }
  49. void init() {
  50. str.resize(0);
  51. str.resize(1, 26);
  52. st.resize(0);
  53. newnode(0, 1);
  54. newnode(-1, 0);
  55. las = 0;
  56. }
  57. };
  58. ul las[maxn + 1];
  59. pam_t pam;
  60. ul T;
  61. ul n;
  62. char s[maxn + 2];
  63. ul head[maxn + 2];
  64. using pulul = std::pair<ul, ul>;
  65. void getlen(ul l, ul r, std::vector<pulul>& v)
  66. {
  67. v.resize(0);
  68. ul cur = las[r];
  69. while (pam.st[head[cur]].len > r - l + 1) {
  70. cur = pam.st[head[cur]].fa;
  71. }
  72. v.push_back(pulul(r - l + 1, pam.st[cur].len - pam.st[pam.st[cur].fa].len));
  73. cur = pam.st[head[cur]].fa;
  74. while (cur) {
  75. v.push_back(pulul(pam.st[cur].len, pam.st[cur].len - pam.st[pam.st[cur].fa].len));
  76. cur = pam.st[head[cur]].fa;
  77. }
  78. }
  79. std::vector<pulul> vs[2];
  80. int main()
  81. {
  82. std::ios::sync_with_stdio(false);
  83. std::cin.tie(0);
  84. iss.tie(0);
  85. oss.tie(0);
  86. std::getline(std::cin, instr, char(0));
  87. iss.str(instr);
  88. iss >> T;
  89. for (ul Case = 1; Case <= T; ++Case) {
  90. iss >> n >> s + 1;
  91. pam.init();
  92. for (ul i = 1; i <= n; ++i) {
  93. pam.add(s[i] - 'a');
  94. las[i] = pam.las;
  95. }
  96. for (ul i = 2; i != pam.st.size(); ++i) {
  97. if (!pam.st[i].fa || pam.st[i].len + pam.st[pam.st[pam.st[i].fa].fa].len != (pam.st[pam.st[i].fa].len << 1)) {
  98. head[i] = i;
  99. } else {
  100. head[i] = head[pam.st[i].fa];
  101. }
  102. }
  103. ul q;
  104. iss >> q;
  105. for (ul t = 1; t <= q; ++t) {
  106. ul a, b, c, d;
  107. iss >> a >> b >> c >> d;
  108. if (b - a != d - c) {
  109. oss << (d - c > b - a ? "sjfnb\n" : "cslnb\n");
  110. continue;
  111. }
  112. getlen(a, b, vs[0]);
  113. getlen(c, d, vs[1]);
  114. bool flag = false;
  115. for (ul i = 0; i != vs[0].size() && i != vs[1].size(); ++i) {
  116. if (vs[0][i].first != vs[1][i].first) {
  117. oss << (vs[0][i].first > vs[1][i].first ? "cslnb\n" : "sjfnb\n");
  118. flag = true;
  119. break;
  120. }
  121. if (vs[0][i].second != vs[1][i].second) {
  122. oss << (vs[0][i].second < vs[1][i].second ? "cslnb\n" : "sjfnb\n");
  123. flag = true;
  124. break;
  125. }
  126. }
  127. if (!flag) {
  128. oss << "draw\n";
  129. }
  130. }
  131. }
  132. std::cout << oss.str();
  133. return 0;
  134. }

C、Tokitsukaze and Colorful Tree 6793

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

  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. class changer {
  11. public:
  12. ul time = 0;
  13. li change = 0;
  14. ul val = 0;
  15. ul nid = 0;
  16. changer()=default;
  17. changer(ul a, li b, ul c, ul d): time(a), change(b), val(c), nid(d) {}
  18. };
  19. const ul maxn = 1e5;
  20. std::vector<changer> changes[maxn + 1];
  21. ul n;
  22. ul col[maxn + 1];
  23. ul val[maxn + 1];
  24. const ul maxq = 1e5;
  25. ul q;
  26. std::vector<ul> edges[maxn + 1];
  27. ll ans[maxq + 2];
  28. ul ldfn[maxn + 1];
  29. ul rdfn[maxn + 1];
  30. ul tim = 0;
  31. void search(ul curr, ul prev)
  32. {
  33. ++tim;
  34. ldfn[curr] = tim;
  35. for (ul next : edges[curr]) {
  36. if (next == prev) {
  37. continue;
  38. }
  39. search(next, curr);
  40. }
  41. rdfn[curr] = tim;
  42. }
  43. li cnt[2];
  44. const ul sz = 1 << 17;
  45. li treeup[2][sz << 1];
  46. li treedown[2][sz << 1];
  47. void insert(ul l, ul r, li v, li tree[])
  48. {
  49. for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {
  50. if (~l & 1) {
  51. tree[l ^ 1] += v;
  52. }
  53. if (r & 1) {
  54. tree[r ^ 1] += v;
  55. }
  56. }
  57. }
  58. li query(ul l, ul r, const li tree[])
  59. {
  60. li ret = 0;
  61. for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {
  62. if (~l & 1) {
  63. ret += tree[l ^ 1];
  64. }
  65. if (r & 1) {
  66. ret += tree[r ^ 1];
  67. }
  68. }
  69. return ret;
  70. }
  71. void insert(ul pos, li v, li tree[])
  72. {
  73. for (tree[pos |= sz] += v, pos >>= 1; pos; pos >>= 1) {
  74. tree[pos] += v;
  75. }
  76. }
  77. li query(ul pos, const li tree[])
  78. {
  79. li ret = tree[pos |= sz];
  80. for (pos >>= 1; pos; pos >>= 1) {
  81. ret += tree[pos];
  82. }
  83. return ret;
  84. }
  85. int main()
  86. {
  87. std::ios::sync_with_stdio(false);
  88. std::cin.tie(0);
  89. iss.tie(0);
  90. oss.tie(0);
  91. std::getline(std::cin, instr, char(0));
  92. iss.str(instr);
  93. iss >> T;
  94. for (ul Case = 1; Case <= T; ++Case) {
  95. iss >> n;
  96. for (ul i = 1; i <= n; ++i) {
  97. edges[i].resize(0);
  98. iss >> col[i];
  99. }
  100. for (ul i = 1; i <= n; ++i) {
  101. iss >> val[i];
  102. changes[col[i]].push_back(changer(0, 1, val[i], i));
  103. }
  104. for (ul i = 1; i <= n - 1; ++i) {
  105. ul u, v;
  106. iss >> u >> v;
  107. edges[u].push_back(v);
  108. edges[v].push_back(u);
  109. }
  110. iss >> q;
  111. for (ul t = 1; t <= q; ++t) {
  112. ul a, b, c;
  113. iss >> a >> b >> c;
  114. changes[col[b]].push_back(changer(t, -1, val[b], b));
  115. if (a == 1) {
  116. val[b] = c;
  117. } else {
  118. col[b] = c;
  119. }
  120. changes[col[b]].push_back(changer(t, 1, val[b], b));
  121. }
  122. for (ul i = 1; i <= q + 1; ++i) {
  123. ans[i] = 0;
  124. }
  125. tim = 0;
  126. search(1, 0);
  127. for (ul c = 1; c <= n; ++c) {
  128. for (ul it = 0; it != 20; ++it) {
  129. for (const auto& change : changes[c]) {
  130. ul type = change.val >> it & 1;
  131. ans[change.time + 1] += ll(change.change) * (ll(cnt[type ^ 1]) << it);
  132. ans[change.time + 1] -= ll(change.change) * (ll(query(ldfn[change.nid] + 1, rdfn[change.nid], treeup[type ^ 1])) << it);
  133. ans[change.time + 1] -= ll(change.change) * (ll(query(ldfn[change.nid], treedown[type ^ 1])) << it);
  134. cnt[type] += change.change;
  135. insert(ldfn[change.nid], change.change, treeup[type]);
  136. insert(ldfn[change.nid] + 1, rdfn[change.nid], change.change, treedown[type]);
  137. }
  138. for (const auto& change : changes[c]) {
  139. ul type = change.val >> it & 1;
  140. cnt[type] -= change.change;
  141. insert(ldfn[change.nid], -change.change, treeup[type]);
  142. insert(ldfn[change.nid] + 1, rdfn[change.nid], -change.change, treedown[type]);
  143. }
  144. }
  145. changes[c].resize(0);
  146. }
  147. for (ul i = 1; i <= q; ++i) {
  148. ans[i + 1] += ans[i];
  149. }
  150. for (ul i = 1; i <= q + 1; ++i) {
  151. oss << ans[i] << '\n';
  152. }
  153. }
  154. std::cout << oss.str();
  155. return 0;
  156. }

D、Tokitsukaze and Multiple 6794

简单题

  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. ul n, p;
  11. ul a;
  12. const ul maxn = 1e5;
  13. ul sa[maxn + 1];
  14. const ul maxp = 1e5;
  15. li ans[maxp];
  16. int main()
  17. {
  18. std::ios::sync_with_stdio(false);
  19. std::cin.tie(0);
  20. iss.tie(0);
  21. oss.tie(0);
  22. std::getline(std::cin, instr, char(0));
  23. iss.str(instr);
  24. for (ul i = 1; i != maxp; ++i) {
  25. ans[i] = -1e9;
  26. }
  27. iss >> T;
  28. for (ul Case = 1; Case <= T; ++Case) {
  29. iss >> n >> p;
  30. sa[0] = 0;
  31. ans[0] = 0;
  32. for (ul i = 1; i <= n; ++i) {
  33. iss >> a;
  34. sa[i] = (a + sa[i - 1]) % p;
  35. ans[sa[i]] = std::max(ans[sa[i]] + 1, ans[sa[i - 1]]);
  36. }
  37. oss << ans[sa[n]] << '\n';
  38. for (ul i = 1; i <= n; ++i) {
  39. ans[sa[i]] = -1e9;
  40. }
  41. }
  42. std::cout << oss.str();
  43. return 0;
  44. }

E、Little W and Contest 6795

简单题

  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. ul n;
  11. const ul maxn = 1e5;
  12. ul fa[maxn + 1];
  13. ul rk[maxn + 1];
  14. ull cnt[maxn + 1][2];
  15. ull c[3];
  16. ull ans;
  17. ull bi2(ull a)
  18. {
  19. return a * (a - 1) >> 1;
  20. }
  21. ull bi3(ull a)
  22. {
  23. return a * (a - 1) * (a - 2) / 6;
  24. }
  25. ul getfather(ul a)
  26. {
  27. return a == fa[a] ? a : fa[a] = getfather(fa[a]);
  28. }
  29. void connect(ul a, ul b)
  30. {
  31. if (rk[a] < rk[b]) {
  32. std::swap(a, b);
  33. }
  34. fa[b] = a;
  35. cnt[a][3] += cnt[b][4];
  36. cnt[a][5] += cnt[b][6];
  37. if (rk[a] == rk[b]) {
  38. ++rk[a];
  39. }
  40. }
  41. int main()
  42. {
  43. std::ios::sync_with_stdio(false);
  44. std::cin.tie(0);
  45. iss.tie(0);
  46. oss.tie(0);
  47. std::getline(std::cin, instr, char(0));
  48. iss.str(instr);
  49. iss >> T;
  50. for (ul Case = 1; Case <= T; ++Case) {
  51. iss >> n;
  52. c[1] = c[2] = 0;
  53. for (ul i = 1; i <= n; ++i) {
  54. rk[i] = 0;
  55. fa[i] = i;
  56. ul tmp;
  57. iss >> tmp;
  58. cnt[i][3 ^ tmp] = 0;
  59. cnt[i][tmp] = 1;
  60. ++c[tmp];
  61. }
  62. ans = bi2(c[2]) * c[1] + bi3(c[2]);
  63. oss << ans % ul(1e9 + 7) << '\n';
  64. for (ul i = 1; i <= n - 1; ++i) {
  65. ul u, v;
  66. iss >> u >> v;
  67. u = getfather(u);
  68. v = getfather(v);
  69. ans -= cnt[u][7] * cnt[v][8] * (c[2] - cnt[u][9] - cnt[v][10]) + cnt[u][11] * cnt[v][12] * (c[2] - cnt[u][13] - cnt[v][14]) + cnt[u][15] * cnt[v][16] * (c[1] - cnt[u][17] - cnt[v][18]) + cnt[u][19] * cnt[v][20] * (c[2] - cnt[u][21] - cnt[v][22]);
  70. connect(u, v);
  71. oss << ans % ul(1e9 + 7) << '\n';
  72. }
  73. }
  74. std::cout << oss.str();
  75. return 0;
  76. }

F、X Number 6796

直接看代码吧,其中的排列组合说明非常复杂。

  1. #pragma GCC target ("pclmul")
  2. #include <bits/stdc++.h>
  3. #include <emmintrin.h>
  4. #include <wmmintrin.h>
  5. std::stringstream iss;
  6. std::stringstream oss;
  7. std::string instr;
  8. using ul = std::uint32_t;
  9. using ull = std::uint64_t;
  10. using li = std::int32_t;
  11. using ll = std::int64_t;
  12. inline ul mul(ul a, ul b) {
  13. auto vc = _mm_clmulepi64_si128(_mm_cvtsi32_si128(a), _mm_cvtsi32_si128(b), 0);
  14. auto vf = _mm_xor_si128(vc, _mm_clmulepi64_si128(_mm_srli_epi64(vc, 32), _mm_set_epi32(0, 0, 1, 141), 0));
  15. return _mm_cvtsi128_si32(_mm_xor_si128(vf, _mm_clmulepi64_si128(_mm_srli_epi64(vf, 32), _mm_set_epi32(0, 0, 1, 141), 0)));
  16. }
  17. ul x, y;
  18. std::mt19937 rnd;
  19. ull n;
  20. ul a[10];
  21. ul b[10];
  22. ull fac[20];
  23. std::unordered_map<ul, ull> subans;
  24. ul cntb[20];
  25. ul cntb3[20];
  26. ul cntamb[20];
  27. ul cntambb[20][23];
  28. ull l, r;
  29. ull bi(ul a, ul b)
  30. {
  31. return fac[a] / fac[b] / fac[a - b];
  32. }
  33. void search2(ul i, ul nct, ul sum, ull prod, ul hash, ul t1, ul t2, ul t3, ul cnt)
  34. {
  35. if (i > nct) {
  36. hash = mul(mul(hash, x) ^ a[0] - b[0], x) ^ sum;
  37. ull tmp1 = fac[sum] / prod;
  38. for (ul i = 1; i <= 19; ++i) {
  39. tmp1 /= fac[cntb[i]];
  40. }
  41. ull tmp2 = bi(9 - t1 - t3, t2);
  42. ull tmp3 = 1;
  43. if (b[0]) {
  44. tmp3 *= bi(cntb[b[0]], 1);
  45. }
  46. for (ul i = 1; i <= 19; ++i) {
  47. tmp3 *= bi(cntb[i] - (b[0] == i), cntb3[i]) * fac[cntb3[i]];
  48. }
  49. ull tmp4 = fac[t2];
  50. ull tmp5 = 1;
  51. for (ul i = 1; i <= 19; ++i) {
  52. if (cntamb[i]) {
  53. ull tmp6 = fac[cntamb[i]];
  54. for (ul j = 0; i + j <= 19; ++j) {
  55. tmp6 /= fac[cntambb[i][j]];
  56. }
  57. tmp5 *= tmp6;
  58. }
  59. }
  60. subans[hash] += tmp1 * tmp2 * tmp3 * tmp4 * tmp5;
  61. return;
  62. }
  63. for (b[i] = (i != 0 && a[i] == a[i - 1]) ? cnt : ul(0); b[i] <= a[i]; ++b[i]) {
  64. ++cntb[b[i]];
  65. if (i && b[i] != a[i] && b[i]) {
  66. ++cntb3[b[i]];
  67. }
  68. if (i && b[i] != a[i]) {
  69. ++cntamb[a[i] - b[i]];
  70. ++cntambb[a[i] - b[i]][b[i]];
  71. }
  72. search2(i + 1, nct, sum + b[i], prod * fac[b[i]], i ? (a[i] == b[i] ? hash : mul(hash, a[i] - b[i] ^ y)) : ul(1), t1 + (i != 0 && b[i] == 0), t2 + (i != 0 && b[i] == a[i]), t3 + (i != 0 && b[i] != a[i] && b[i] != 0), b[i]);
  73. --cntb[b[i]];
  74. if (i && b[i] != a[i] && b[i]) {
  75. --cntb3[b[i]];
  76. }
  77. if (i && b[i] != a[i]) {
  78. --cntamb[a[i] - b[i]];
  79. --cntambb[a[i] - b[i]][b[i]];
  80. }
  81. }
  82. }
  83. void search(ul i, ul cnt, ul sum)
  84. {
  85. if (i > 9) {
  86. return;
  87. }
  88. if (i == 0) {
  89. for (a[0] = 1; a[0] <= 19; ++a[0]) {
  90. search(1, 1, a[0]);
  91. search2(0, i, 0, 1, 1, 0, 0, 0, 0);
  92. }
  93. } else {
  94. for (a[i] = cnt; sum + a[i] <= 19 && a[i] < a[0]; ++a[i]) {
  95. search(i + 1, a[i], sum + a[i]);
  96. search2(0, i, 0, 1, 1, 0, 0, 0, 0);
  97. }
  98. }
  99. }
  100. ul d;
  101. ul cnt[10];
  102. bool check(ull x, ul d)
  103. {
  104. static ul cnt[10];
  105. std::memset(cnt, 0, sizeof(cnt));
  106. while (x) {
  107. ++cnt[x % 10];
  108. x /= 10;
  109. }
  110. for (ul i = 0; i <= 9; ++i) {
  111. if (cnt[i] >= cnt[d] && i != d) {
  112. return false;
  113. }
  114. }
  115. return true;
  116. }
  117. ull calc2(ull v, ul len, ul d)
  118. {
  119. ull qv = v;
  120. std::memset(cnt, 0, sizeof(cnt));
  121. while (v) {
  122. ++cnt[v % 10];
  123. v /= 10;
  124. }
  125. ul hash = 1;
  126. for (ul i = 0; i <= 9; ++i) {
  127. if (i != d && cnt[i]) {
  128. hash = mul(hash, y ^ cnt[i]);
  129. }
  130. }
  131. hash = mul(mul(hash, x) ^ cnt[d], x) ^ len;
  132. auto it = subans.find(hash);
  133. return it != subans.end() ? it->second : ull(0);
  134. }
  135. ull calc(ull l, ull r, ul d)
  136. {
  137. ull ans = 0;
  138. ul len = 0;
  139. for ( ; r >= l; ++len) {
  140. if (l / 10 == r / 10 && (l % 10 != 0 || r % 10 != 9)) {
  141. for (ull i = l; i <= r; ++i) {
  142. ans += calc2(i, len, d);
  143. }
  144. break;
  145. }
  146. if (l % 10 != 0) {
  147. for (ull i = l; i / 10 == l / 10; ++i) {
  148. ans += calc2(i, len, d);
  149. }
  150. l = l / 10 + 1;
  151. } else {
  152. l = l / 10;
  153. }
  154. if (r % 10 != 9) {
  155. for (ull i = r; i / 10 == r / 10; --i) {
  156. ans += calc2(i, len, d);
  157. }
  158. r = r / 10 - 1;
  159. } else {
  160. r = r / 10;
  161. }
  162. }
  163. return ans;
  164. }
  165. ul T;
  166. int main()
  167. {
  168. std::ios::sync_with_stdio(false);
  169. std::cin.tie(0);
  170. iss.tie(0);
  171. oss.tie(0);
  172. std::getline(std::cin, instr, char(0));
  173. iss.str(instr);
  174. rnd.seed(std::time(0));
  175. x = rnd();
  176. y = rnd();
  177. fac[0] = 1;
  178. for (ul i = 1; i <= 19; ++i) {
  179. fac[i] = fac[i - 1] * i;
  180. }
  181. search(0, 0, 0);
  182. for (ul len = 0; len <= 10; ++len) {
  183. for (ull v = 1; v <= 999; ++v) {
  184. calc2(v, len, 1);
  185. }
  186. }
  187. iss >> T;
  188. for (ul Case = 1; Case <= T; ++Case) {
  189. iss >> l >> r >> d;
  190. ull ans = 0;
  191. for (ull i = 1; i <= 1e18; i *= 10) {
  192. ull j = i * 10 - 1;
  193. if (i <= r && j >= l) {
  194. ans += calc(std::max(i, l), std::min(j, r), d);
  195. }
  196. }
  197. oss << ans << '\n';
  198. }
  199. std::cout << oss.str();
  200. return 0;
  201. }

G、Tokitsukaze and Rescue 6797

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

  1. #pragma GCC target ("pclmul")
  2. #include <bits/stdc++.h>
  3. #include <emmintrin.h>
  4. #include <wmmintrin.h>
  5. std::stringstream iss;
  6. std::stringstream oss;
  7. std::string instr;
  8. using ul = std::uint32_t;
  9. using ull = std::uint64_t;
  10. using li = std::int32_t;
  11. using ll = std::int64_t;
  12. ul T;
  13. ul n, k;
  14. const ul maxn = 50;
  15. ul edge[maxn + 1][maxn + 1];
  16. ul dis1[6][maxn + 1];
  17. ul disn[6][maxn + 1];
  18. ul ans = 0;
  19. bool ban[maxn + 1][maxn + 1];
  20. ul tim;
  21. ul vis[maxn + 1];
  22. void search(ul cnt)
  23. {
  24. for (ul i = 1; i <= n; ++i) {
  25. dis1[cnt][i] = 1e9;
  26. disn[cnt][i] = 1e9;
  27. }
  28. dis1[cnt][25] = 0;
  29. ++tim;
  30. while (true) {
  31. ul tmp = 0;
  32. for (ul i = 1; i <= n; ++i) {
  33. if (vis[i] != tim) {
  34. if (!tmp || dis1[cnt][tmp] > dis1[cnt][i]) {
  35. tmp = i;
  36. }
  37. }
  38. }
  39. if (!tmp) {
  40. break;
  41. }
  42. vis[tmp] = tim;
  43. for (ul i = 1; i <= n; ++i) {
  44. if (!ban[tmp][i]) {
  45. dis1[cnt][i] = std::min(dis1[cnt][i], dis1[cnt][tmp] + edge[tmp][i]);
  46. }
  47. }
  48. }
  49. disn[cnt][n] = 0;
  50. ++tim;
  51. while (true) {
  52. ul tmp = 0;
  53. for (ul i = 1; i <= n; ++i) {
  54. if (vis[i] != tim) {
  55. if (!tmp || disn[cnt][tmp] > disn[cnt][i]) {
  56. tmp = i;
  57. }
  58. }
  59. }
  60. if (!tmp) {
  61. break;
  62. }
  63. vis[tmp] = tim;
  64. for (ul i = 1; i <= n; ++i) {
  65. if (!ban[tmp][i]) {
  66. disn[cnt][i] = std::min(disn[cnt][i], disn[cnt][tmp] + edge[tmp][i]);
  67. }
  68. }
  69. }
  70. if (cnt == k) {
  71. ans = std::max(dis1[cnt][n], ans);
  72. } else {
  73. for (ul a = 1; a + 1 <= n; ++a) {
  74. for (ul b = a + 1; b <= n; ++b) {
  75. if (ban[a][b]) {
  76. continue;
  77. }
  78. if (dis1[cnt][a] + edge[a][b] + disn[cnt][b] == dis1[cnt][n] || dis1[cnt][b] + edge[b][a] + disn[cnt][a] == dis1[cnt][n]) {
  79. ban[a][b] = ban[b][a] = true;
  80. search(cnt + 1);
  81. ban[a][b] = ban[b][a] = false;
  82. }
  83. }
  84. }
  85. }
  86. }
  87. int main()
  88. {
  89. std::ios::sync_with_stdio(false);
  90. std::cin.tie(0);
  91. iss.tie(0);
  92. oss.tie(0);
  93. std::getline(std::cin, instr, char(0));
  94. iss.str(instr);
  95. iss >> T;
  96. for (ul Case = 1; Case <= T; ++Case) {
  97. iss >> n >> k;
  98. for (ul i = 1; i + 1 <= n; ++i) {
  99. for (ul j = i + 1; j <= n; ++j) {
  100. ul u, v, w;
  101. iss >> u >> v >> w;
  102. edge[v][u] = edge[u][v] = w;
  103. }
  104. }
  105. ans = 0;
  106. search(0);
  107. oss << ans << '\n';
  108. }
  109. std::cout << oss.str();
  110. return 0;
  111. }

H、Triangle Collision 6798

简单题

  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. using lf = double;
  10. class vec {
  11. public:
  12. lf x = 0;
  13. lf y = 0;
  14. vec()=default;
  15. vec(lf a, lf b): x(a), y(b) {}
  16. };
  17. vec operator+(const vec& a, const vec& b)
  18. {
  19. return vec(a.x + b.x, a.y + b.y);
  20. }
  21. vec operator-(const vec& a, const vec& b)
  22. {
  23. return vec(a.x - b.x, a.y - b.y);
  24. }
  25. vec operator*(lf a, const vec& b)
  26. {
  27. return vec(a * b.x, a * b.y);
  28. }
  29. lf operator*(const vec& a, const vec& b)
  30. {
  31. return a.x * b.x + a.y * b.y;
  32. }
  33. ull cnt(lf a, lf b)
  34. {
  35. return ll(std::floor(std::max(a, b))) - ll(std::ceil(std::min(a, b))) + 1;
  36. }
  37. lf l;
  38. const lf s3 = std::sqrt(lf(3));
  39. ull query(const vec& s, const vec& t)
  40. {
  41. ull ret = 0;
  42. ret += cnt(s * vec(0, 1) / s3 / l * lf(2), t * vec(0, 1) / s3 / l * lf(2));
  43. ret += cnt(s * vec(s3 * lf(0.5), 0.5) / s3 / l * lf(2), t * vec(s3 * lf(0.5), 0.5) / s3 / l * lf(2));
  44. ret += cnt(s * vec(-s3 * lf(0.5), 0.5) / s3 / l * lf(2), t * vec(-s3 * lf(0.5), 0.5) / s3 / l * lf(2));
  45. return ret;
  46. }
  47. ul T;
  48. const lf eps = 1e-4;
  49. int main()
  50. {
  51. std::ios::sync_with_stdio(false);
  52. std::cin.tie(0);
  53. iss.tie(0);
  54. oss.tie(0);
  55. std::getline(std::cin, instr, char(0));
  56. iss.str(instr);
  57. iss >> T;
  58. for (ul Case = 1; Case <= T; ++Case) {
  59. vec s, v;
  60. ul k;
  61. iss >> l >> s.x >> s.y >> v.x >> v.y >> k;
  62. lf a = 0, b = k * l;
  63. while (b - a > std::max(a, lf(1)) * eps) {
  64. lf mid = (a + b) * lf(0.5);
  65. vec t = mid * v + s;
  66. ull cnt = query(s + vec(l * lf(0.5), 0), t + vec(l * lf(0.5), 0));
  67. if (cnt >= k) {
  68. b = mid;
  69. } else {
  70. a = mid;
  71. }
  72. }
  73. oss << std::fixed << std::setprecision(6) << (a + b) * lf(0.5) << '\n';
  74. }
  75. std::cout << oss.str();
  76. return 0;
  77. }

I、Parentheses Matching 6799

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

  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. char s[maxn + 2];
  12. char s2[maxn + 2];
  13. int main()
  14. {
  15. std::ios::sync_with_stdio(false);
  16. std::cin.tie(0);
  17. iss.tie(0);
  18. oss.tie(0);
  19. std::getline(std::cin, instr, char(0));
  20. iss.str(instr);
  21. iss >> T;
  22. for (ul Case = 1; Case <= T; ++Case) {
  23. iss >> s + 1;
  24. ul n = std::strlen(s + 1);
  25. li cntstar = 0;
  26. li pm = 0;
  27. for (ul i = 1; i <= n; ++i) {
  28. if (s[i] == '(') {
  29. ++pm;
  30. } else if (s[i] == ')') {
  31. --pm;
  32. } else {
  33. ++cntstar;
  34. }
  35. }
  36. if (pm - cntstar > 0 || pm + cntstar < 0) {
  37. oss << "No solution!\n";
  38. continue;
  39. }
  40. if (pm < 0) {
  41. for (ul i = 1; i <= n && pm; ++i) {
  42. if (s[i] == '*') {
  43. ++pm;
  44. --cntstar;
  45. s[i] = '(';
  46. }
  47. }
  48. }
  49. if (pm > 0) {
  50. for (ul i = n; i >= 1 && pm; --i) {
  51. if (s[i] == '*') {
  52. --pm;
  53. --cntstar;
  54. s[i] = ')';
  55. }
  56. }
  57. }
  58. li l = -1, r = (cntstar >> 1) + 1;
  59. while (l + 1 != r) {
  60. li mid = l + (r - l >> 1);
  61. std::memcpy(s2 + 1, s + 1, sizeof(char) * n);
  62. li cnt = mid;
  63. for (ul i = 1; i <= n && cnt; ++i) {
  64. if (s[i] == '*') {
  65. --cnt;
  66. s2[i] = '(';
  67. }
  68. }
  69. cnt = mid;
  70. for (ul i = n; i >= 1 && cnt; --i) {
  71. if (s[i] == '*') {
  72. --cnt;
  73. s2[i] = ')';
  74. }
  75. }
  76. li state = 0;
  77. for (ul i = 1; i <= n; ++i) {
  78. if (s2[i] == '(') {
  79. ++state;
  80. } else if (s2[i] == ')') {
  81. --state;
  82. if (state < 0) {
  83. break;
  84. }
  85. }
  86. }
  87. if (state == 0) {
  88. r = mid;
  89. } else {
  90. l = mid;
  91. }
  92. }
  93. if (r == (cntstar >> 1) + 1) {
  94. oss << "No solution!\n";
  95. } else {
  96. std::memcpy(s2 + 1, s + 1, sizeof(char) * n);
  97. li cnt = r;
  98. for (ul i = 1; i <= n && cnt; ++i) {
  99. if (s[i] == '*') {
  100. --cnt;
  101. s2[i] = '(';
  102. }
  103. }
  104. cnt = r;
  105. for (ul i = n; i >= 1 && cnt; --i) {
  106. if (s[i] == '*') {
  107. --cnt;
  108. s2[i] = ')';
  109. }
  110. }
  111. for (ul i = 1; i <= n; ++i) {
  112. if (s2[i] != '*') {
  113. oss << s2[i];
  114. }
  115. }
  116. oss << '\n';
  117. }
  118. }
  119. std::cout << oss.str();
  120. return 0;
  121. }

J、Play osu! on Your Tablet 6800

官方题解如下:
无标题.png-192.7kB
下方代码采用纯分治写法,不使用数据结构,故实际时间复杂度为。综合度很高的分治题。

  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 li maxn = 1e5;
  11. li n;
  12. ll x[maxn + 1];
  13. ll y[maxn + 1];
  14. ll dis(ll a, ll b)
  15. {
  16. return std::max(a, b) - std::min(a, b);
  17. }
  18. ll ans[maxn + 1];
  19. class node {
  20. public:
  21. li i = 0;
  22. bool query = false;
  23. bool insert = false;
  24. node()=default;
  25. node(li i, bool query, bool insert): i(i), query(query), insert(insert) {}
  26. ll xx() const {
  27. return x[i + query];
  28. }
  29. ll yy() const {
  30. return y[i + query];
  31. }
  32. };
  33. const ll inf = 1e17;
  34. void cdqy(li l, li r, const std::vector<node>& vx, ll xdir)
  35. {
  36. ll mn = inf;
  37. for (li i = l; i <= r; ++i) {
  38. if (vx[i].insert) {
  39. mn = std::min(mn, ans[vx[i].i] - xdir * vx[i].xx() - vx[i].yy());
  40. } else {
  41. ans[vx[i].i] = std::min(ans[vx[i].i], mn + xdir * vx[i].xx() + vx[i].yy());
  42. }
  43. }
  44. mn = inf;
  45. for (li i = r; i >= l; --i) {
  46. if (vx[i].insert) {
  47. mn = std::min(mn, ans[vx[i].i] - xdir * vx[i].xx() + vx[i].yy());
  48. } else {
  49. ans[vx[i].i] = std::min(ans[vx[i].i], mn + xdir * vx[i].xx() - vx[i].yy());
  50. }
  51. }
  52. }
  53. void cdqx(li l, li r, const std::vector<node>& vi)
  54. {
  55. if (l > r || l == r) {
  56. return;
  57. }
  58. static std::vector<node> v1;
  59. static std::vector<node> v2;
  60. li midl = l + r >> 1;
  61. li midr = midl + 1;
  62. v1.resize(0);
  63. v2.resize(0);
  64. ul v1flag = 0, v2flag = 0;
  65. for (li i = l; i <= midl; ++i) {
  66. if (vi[i].insert) {
  67. v1.push_back(vi[i]);
  68. v1flag |= 1;
  69. } else {
  70. v2.push_back(vi[i]);
  71. v2flag |= 2;
  72. }
  73. }
  74. for (li i = midr; i <= r; ++i) {
  75. if (vi[i].query) {
  76. v1.push_back(vi[i]);
  77. v1flag |= 2;
  78. } else {
  79. v2.push_back(vi[i]);
  80. v2flag |= 1;
  81. }
  82. }
  83. if (v1flag == 3) {
  84. std::sort(v1.begin(), v1.end(), [](const node& a, const node& b) {return a.yy() < b.yy();});
  85. cdqy(0, v1.size() - 1, v1, 1);
  86. }
  87. if (v2flag == 3) {
  88. std::sort(v2.begin(), v2.end(), [](const node& a, const node& b) {return a.yy() < b.yy();});
  89. cdqy(0, v2.size() - 1, v2, -1);
  90. }
  91. if (v1flag & v2flag >> 1 & 1) {
  92. cdqx(l, midl, vi);
  93. }
  94. if (v1flag >> 1 & v2flag & 1) {
  95. cdqx(midr, r, vi);
  96. }
  97. }
  98. void cdqi1(li l, li r)
  99. {
  100. if (l == r) {
  101. if (l != n) {
  102. ans[l] = dis(x[l], x[l + 1]) + dis(y[l], y[l + 1]);
  103. }
  104. return;
  105. }
  106. static std::vector<node> v;
  107. li midl = l + r >> 1;
  108. li midr = midl + 1;
  109. cdqi1(l, midl);
  110. v.resize(0);
  111. for (li i = l; i <= midl; ++i) {
  112. v.push_back(node(i, true, false));
  113. }
  114. for (li i = midr; i <= r; ++i) {
  115. v.push_back(node(i, false, true));
  116. }
  117. std::sort(v.begin(), v.end(), [](const node& a, const node& b){return a.xx() < b.xx();});
  118. cdqx(0, v.size() - 1, v);
  119. cdqi1(midr, r);
  120. }
  121. void cdqi2(li l, li r)
  122. {
  123. if (l > r) {
  124. return;
  125. }
  126. if (l == r) {
  127. if (l != n) {
  128. ans[l] -= dis(x[l], x[l + 1]) + dis(y[l], y[l + 1]);
  129. }
  130. return;
  131. }
  132. static std::vector<node> v;
  133. li midl = l + r >> 1;
  134. li midr = midl + 1;
  135. cdqi2(l, midl);
  136. v.resize(0);
  137. for (li i = l; i <= midl; ++i) {
  138. v.push_back(node(i, false, true));
  139. }
  140. for (li i = midr; i <= r; ++i) {
  141. v.push_back(node(i, true, false));
  142. }
  143. std::sort(v.begin(), v.end(), [](const node& a, const node& b){return a.xx() < b.xx();});
  144. cdqx(0, v.size() - 1, v);
  145. cdqi2(midr, r);
  146. }
  147. int main()
  148. {
  149. std::ios::sync_with_stdio(false);
  150. std::cin.tie(0);
  151. iss.tie(0);
  152. oss.tie(0);
  153. std::getline(std::cin, instr, char(0));
  154. iss.str(instr);
  155. iss >> T;
  156. for (ul Case = 1; Case <= T; ++Case) {
  157. iss >> n;
  158. ll sum = 0;
  159. for (li i = 1; i <= n; ++i) {
  160. iss >> x[i] >> y[i];
  161. if (i != 1) {
  162. sum += dis(x[i], x[i - 1]) + dis(y[i], y[i - 1]);
  163. }
  164. }
  165. std::memset(ans + 1, 0, sizeof(ll) * n);
  166. cdqi1(1, n);
  167. cdqi2(1, n - 1);
  168. ll out = inf;
  169. for (li i = 1; i <= n; ++i) {
  170. out = std::min(out, ans[i] + sum);
  171. }
  172. oss << out << '\n';
  173. }
  174. std::cout << oss.str();
  175. return 0;
  176. }

K、Game on a Circle 6801

被删除的时候是其第次被访问,于是显然是独立同分布的。且,官方题解如下:
无标题.png-103.8kB

  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. using vul = std::vector<ul>;
  10. const ul base = 998244353;
  11. ul plus(ul a, ul b)
  12. {
  13. return a + b < base ? a + b : a + b - base;
  14. }
  15. ul minus(ul a, ul b)
  16. {
  17. return a < b ? a + base - b : a - b;
  18. }
  19. ul mul(ul a, ul b)
  20. {
  21. return ull(a) * ull(b) % base;
  22. }
  23. void exgcd(li a, li b, li& x, li& y)
  24. {
  25. if (b) {
  26. exgcd(b, a % b, y, x);
  27. y -= x * (a / b);
  28. } else {
  29. x = 1;
  30. y = 0;
  31. }
  32. }
  33. ul inverse(ul a)
  34. {
  35. li x, y;
  36. exgcd(a, base, x, y);
  37. return x < 0 ? x + li(base) : x;
  38. }
  39. ul pow(ul a, ul b)
  40. {
  41. ul ret = 1;
  42. ul temp = a;
  43. while (b) {
  44. if (b & 1) {
  45. ret = mul(ret, temp);
  46. }
  47. temp = mul(temp, temp);
  48. b >>= 1;
  49. }
  50. return ret;
  51. }
  52. class polynomial : public vul {
  53. public:
  54. void clearzero() {
  55. while (size() && !back()) {
  56. pop_back();
  57. }
  58. }
  59. polynomial()=default;
  60. polynomial(const vul& a): vul(a) { }
  61. polynomial(vul&& a): vul(std::move(a)) { }
  62. ul degree() const {
  63. return size() - 1;
  64. }
  65. ul operator()(ul x) const {
  66. ul ret = 0;
  67. for (ul i = size() - 1; ~i; --i) {
  68. ret = mul(ret, x);
  69. ret = plus(ret, vul::operator[](i));
  70. }
  71. return ret;
  72. }
  73. };
  74. class ntt_t {
  75. public:
  76. static const ul lgsz = 21;
  77. static const ul sz = 1 << lgsz;
  78. static const ul g = 3;
  79. ul w[sz + 1];
  80. ul leninv[lgsz + 1];
  81. ntt_t() {
  82. ul wn = pow(g, (base - 1) >> lgsz);
  83. w[0] = 1;
  84. for (ul i = 1; i <= sz; ++i) {
  85. w[i] = mul(w[i - 1], wn);
  86. }
  87. leninv[lgsz] = inverse(sz);
  88. for (ul i = lgsz - 1; ~i; --i) {
  89. leninv[i] = plus(leninv[i + 1], leninv[i + 1]);
  90. }
  91. }
  92. void operator()(vul& v, ul& n, bool inv) {
  93. ul lgn = 0;
  94. while ((1 << lgn) < n) {
  95. ++lgn;
  96. }
  97. n = 1 << lgn;
  98. v.resize(n, 0);
  99. for (ul i = 0, j = 0; i != n; ++i) {
  100. if (i < j) {
  101. std::swap(v[i], v[j]);
  102. }
  103. ul k = n >> 1;
  104. while (k & j) {
  105. j &= ~k;
  106. k >>= 1;
  107. }
  108. j |= k;
  109. }
  110. for (ul lgmid = 0; (1 << lgmid) != n; ++lgmid) {
  111. ul mid = 1 << lgmid;
  112. ul len = mid << 1;
  113. for (ul i = 0; i != n; i += len) {
  114. for (ul j = 0; j != mid; ++j) {
  115. ul t0 = v[i + j];
  116. ul t1 = mul(w[inv ? (len - j << lgsz - lgmid - 1) : (j << lgsz - lgmid - 1)], v[i + j + mid]);
  117. v[i + j] = plus(t0, t1);
  118. v[i + j + mid] = minus(t0, t1);
  119. }
  120. }
  121. }
  122. if (inv) {
  123. for (ul i = 0; i != n; ++i) {
  124. v[i] = mul(v[i], leninv[lgn]);
  125. }
  126. }
  127. }
  128. } ntt;
  129. polynomial& operator*=(polynomial& a, const polynomial& b)
  130. {
  131. if (!b.size() || !a.size()) {
  132. a.resize(0);
  133. return a;
  134. }
  135. polynomial temp = b;
  136. ul npmp1 = a.size() + b.size() - 1;
  137. if (ull(a.size()) * ull(b.size()) <= ull(npmp1) * ull(50)) {
  138. temp.resize(0);
  139. temp.resize(npmp1, 0);
  140. for (ul i = 0; i != a.size(); ++i) {
  141. for (ul j = 0; j != b.size(); ++j) {
  142. temp[i + j] = plus(temp[i + j], mul(a[i], b[j]));
  143. }
  144. }
  145. a = temp;
  146. a.clearzero();
  147. return a;
  148. }
  149. ntt(a, npmp1, false);
  150. ntt(temp, npmp1, false);
  151. for (ul i = 0; i != npmp1; ++i) {
  152. a[i] = mul(a[i], temp[i]);
  153. }
  154. ntt(a, npmp1, true);
  155. a.clearzero();
  156. return a;
  157. }
  158. polynomial operator*(const polynomial& a, const polynomial& b)
  159. {
  160. polynomial ret = a;
  161. return ret *= b;
  162. }
  163. ul T;
  164. ul n, a, b, c;
  165. const ul maxn = 1e6;
  166. ul fac[maxn + 1];
  167. ul fiv[maxn + 1];
  168. ul inv[maxn + 1];
  169. polynomial alpha, beta;
  170. ul f[maxn + 1];
  171. ul qpow[maxn + 1];
  172. int main()
  173. {
  174. std::ios::sync_with_stdio(false);
  175. std::cin.tie(0);
  176. iss.tie(0);
  177. oss.tie(0);
  178. std::getline(std::cin, instr, char(0));
  179. iss.str(instr);
  180. fac[0] = 1;
  181. for (ul i = 1; i <= maxn; ++i) {
  182. fac[i] = mul(fac[i - 1], i);
  183. }
  184. fiv[maxn] = inverse(fac[maxn]);
  185. for (ul i = maxn; i >= 1; --i) {
  186. fiv[i - 1] = mul(fiv[i], i);
  187. inv[i] = mul(fiv[i], fac[i - 1]);
  188. }
  189. iss >> T;
  190. for (ul Case = 1; Case <= T; ++Case) {
  191. iss >> n >> a >> b >> c;
  192. ul p = mul(a, inverse(b));
  193. ul q = minus(1, p);
  194. f[0] = 1;
  195. f[1] = plus(mul(c - 1, q), n - c);
  196. for (ul i = 1; i + 1 <= n - 1; ++i) {
  197. f[i + 1] = mul(inv[i + 1], plus(mul(plus(mul(c - 1, q), minus(minus(n, c), mul(plus(q, 1), i))), f[i]), mul(mul(q, n - i), f[i - 1])));
  198. }
  199. alpha.resize(n);
  200. beta.resize(n);
  201. qpow[0] = 1;
  202. for (ul i = 1; i <= n; ++i) {
  203. qpow[i] = mul(qpow[i - 1], q);
  204. }
  205. for (ul i = 0; i <= n - 1; ++i) {
  206. alpha[i] = mul(mul(fac[n - 1 - i], f[n - 1 - i]), inverse(minus(1, qpow[n - i])));
  207. beta[i] = (i & 1) ? minus(0, fiv[i]) : fiv[i];
  208. }
  209. alpha *= beta;
  210. alpha.resize(n, 0);
  211. for (ul i = 0; i <= n - 1; ++i) {
  212. oss << mul(p, mul(alpha[i], fiv[n - 1 - i])) << '\n';
  213. }
  214. }
  215. std::cout << oss.str();
  216. return 0;
  217. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注