[关闭]
@qq290637843 2021-05-09T11:42:19.000000Z 字数 23178 阅读 445

2019南昌

题目见https://www.jisuanke.com/contest/12755/challenges

A、9102

先解决没有回溯要求的问题。由于要求能删点,所以并查集的写法要加一些虚点,让实点绝对不会成为父节点,而只有实点才会被删除,所以就保证了算法的正确性。
接着,先把操作离线,得到一个版本树,于是就是在这棵树上深度优先搜索,然后可持久化数组。因为该问题实际是用三个数组维护并查集,所以就是对该三数组的版本信息保存,存法就是数组中每个元素实际上是一个栈。本题空间要求比较死,所以用前向链表实现栈。

  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 maxm = 1e6;
  7. const ul maxn = 1e6;
  8. class node {
  9. public:
  10. ul next = 0;
  11. ul val = 0;
  12. };
  13. ul tot = 0;
  14. ul remain = 0;
  15. node nodes[4 * maxn + 6 * maxm + 1];
  16. ul stack[4 * maxn + 6 * maxm + 1];
  17. void push_front(ul& a, ul b)
  18. {
  19. ul tmp;
  20. if (remain) {
  21. tmp = stack[remain];
  22. --remain;
  23. } else {
  24. ++tot;
  25. tmp = tot;
  26. }
  27. nodes[tmp].next = a;
  28. nodes[tmp].val = b;
  29. a = tmp;
  30. }
  31. void pop_front(ul& a)
  32. {
  33. ++remain;
  34. stack[remain] = a;
  35. a = nodes[a].next;
  36. }
  37. ul n, m;
  38. ul query(const ul v[], ul index)
  39. {
  40. return nodes[v[index]].val;
  41. }
  42. void change(ul v[], ul index, ul val, ul& changes)
  43. {
  44. push_front(v[index], val);
  45. push_front(changes, index);
  46. }
  47. ul op[maxm + 1];
  48. ul k[maxm + 1];
  49. ul a[maxm + 1];
  50. ul b[maxm + 1];
  51. ul fa[maxn + maxn + 1];
  52. ul rk[maxn + 1];
  53. ul sz[maxn + 1];
  54. ul sons[maxm + 1];
  55. ul ans[maxm + 1];
  56. ul getfather(ul x)
  57. {
  58. if (!x) {
  59. return x;
  60. }
  61. ul f = query(fa, x);
  62. return f == x ? x : getfather(f);
  63. }
  64. void connect(ul x, ul y, ul& fac, ul& rkc, ul& szc)
  65. {
  66. x = getfather(x);
  67. y = getfather(y);
  68. if (x == y || x == 0 || y == 0) {
  69. return;
  70. }
  71. ul rkx = query(rk, x);
  72. ul rky = query(rk, y);
  73. if (rkx < rky) {
  74. change(fa, x, y, fac);
  75. change(sz, y, query(sz, x) + query(sz, y), szc);
  76. } else if (rkx > rky) {
  77. change(fa, y, x, fac);
  78. change(sz, x, query(sz, x) + query(sz, y), szc);
  79. } else {
  80. change(fa, x, y, fac);
  81. change(sz, y, query(sz, x) + query(sz, y), szc);
  82. change(rk, y, rky + 1, rkc);
  83. }
  84. }
  85. void search(ul curr)
  86. {
  87. ul fac = 0;
  88. ul rkc = 0;
  89. ul szc = 0;
  90. if (curr == 0) {
  91. for (ul i = 1; i <= n; ++i) {
  92. push_front(fa[i + n], i);
  93. push_front(fa[i], i);
  94. push_front(rk[i], 1);
  95. push_front(sz[i], 1);
  96. }
  97. } else {
  98. ul i = curr;
  99. if (op[i] == 1) {
  100. connect(a[i] + n, b[i] + n, fac, rkc, szc);
  101. } else if (op[i] == 2) {
  102. ul ta = getfather(a[i] + n);
  103. if (ta) {
  104. change(sz, ta, query(sz, ta) - 1, szc);
  105. change(fa, a[i] + n, 0, fac);
  106. }
  107. } else if (op[i] == 3) {
  108. ul ta = getfather(a[i] + n);
  109. ul tb = getfather(b[i] + n);
  110. if (ta && tb && ta != tb) {
  111. change(sz, ta, query(sz, ta) - 1, szc);
  112. change(sz, tb, query(sz, tb) + 1, szc);
  113. change(fa, a[i] + n, tb, fac);
  114. }
  115. } else if (op[i] == 4) {
  116. ul ta = getfather(a[i] + n);
  117. ul tb = getfather(b[i] + n);
  118. ans[i] = ta && tb && ta == tb ? 1 : 0;
  119. } else if (op[i] == 5) {
  120. ul ta = getfather(a[i] + n);
  121. if (!ta) {
  122. ans[i] = 0;
  123. } else {
  124. ans[i] = query(sz, ta);
  125. }
  126. }
  127. }
  128. for (ul eid = sons[curr]; eid; eid = nodes[eid].next) {
  129. ul next = nodes[eid].val;
  130. search(next);
  131. }
  132. if (curr != 0) {
  133. while (fac) {
  134. pop_front(fa[nodes[fac].val]);
  135. pop_front(fac);
  136. }
  137. while (rkc) {
  138. pop_front(rk[nodes[rkc].val]);
  139. pop_front(rkc);
  140. }
  141. while (szc) {
  142. pop_front(sz[nodes[szc].val]);
  143. pop_front(szc);
  144. }
  145. }
  146. }
  147. int main()
  148. {
  149. std::scanf("%u%u", &n, &m);
  150. for (ul i = 1; i <= m; ++i) {
  151. std::scanf("%u%u", &op[i], &k[i]);
  152. push_front(sons[k[i]], i);
  153. if (op[i] == 1 || op[i] == 3 || op[i] == 4) {
  154. std::scanf("%u%u", &a[i], &b[i]);
  155. } else {
  156. std::scanf("%u", &a[i]);
  157. }
  158. }
  159. search(0);
  160. for (ul i = 1; i <= m; ++i) {
  161. if (op[i] == 4) {
  162. std::printf(ans[i] ? "Yes\n" : "No\n");
  163. } else if (op[i] == 5) {
  164. std::printf("%u\n", ans[i]);
  165. }
  166. }
  167. return 0;
  168. }

B、A Funny Bipartite Graph

暴搜就能过。

  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 = 18;
  7. ul T;
  8. ul n;
  9. char str[maxn + 1];
  10. ul a[maxn];
  11. ul g[maxn];
  12. std::vector<ul> rg[maxn];
  13. ul m[maxn][4];
  14. ul rdeg[maxn];
  15. const ul inf = 1e9;
  16. ul ans;
  17. ul ord[maxn];
  18. ul reach[1 << maxn];
  19. ul ldeg[maxn];
  20. void search(ul i, ul remainl, ul cans, ul alr)
  21. {
  22. if ((alr | reach[remainl]) != (1 << n) - 1) {
  23. return;
  24. }
  25. if (ans <= cans) {
  26. return;
  27. }
  28. if (i == n) {
  29. ans = cans;
  30. return;
  31. }
  32. ul v = ord[i];
  33. for (ul u : rg[v]) {
  34. if (!(1 << u & remainl)) {
  35. continue;
  36. }
  37. ul nans = cans - m[u][ldeg[u]];
  38. ++ldeg[u];
  39. nans += m[u][ldeg[u]];
  40. search(i + 1, remainl & ~a[u], nans, alr | 1 << v);
  41. --ldeg[u];
  42. }
  43. }
  44. int main()
  45. {
  46. std::scanf("%u", &T);
  47. for (ul Case = 1; Case <= T; ++Case) {
  48. std::scanf("%u", &n);
  49. for (ul i = 0; i <= n - 1; ++i) {
  50. rdeg[i] = 0;
  51. ldeg[i] = 0;
  52. ord[i] = i;
  53. rg[i].resize(0);
  54. }
  55. for (ul i = 0; i <= n - 1; ++i) {
  56. std::scanf("%s", str);
  57. g[i] = 0;
  58. for (ul j = 0; j <= n - 1; ++j) {
  59. g[i] |= ul(str[j] - '0') << j;
  60. rdeg[j] += ul(str[j] - '0');
  61. if (str[j] - '0') {
  62. rg[j].push_back(i);
  63. }
  64. }
  65. }
  66. for (ul i = 1; i < (1 << n); ++i) {
  67. ul t = 31 - __builtin_clz(i);
  68. reach[i] = reach[i & ~(1 << t)] | g[t];
  69. }
  70. for (ul i = 0; i <= n - 1; ++i) {
  71. std::scanf("%s", str);
  72. a[i] = 0;
  73. for (ul j = 0; j <= n - 1; ++j) {
  74. a[i] |= ul(str[j] - '0') << j;
  75. }
  76. }
  77. for (ul i = 0; i <= n - 1; ++i) {
  78. std::scanf("%u", &m[i][1]);
  79. m[i][2] = m[i][1] * m[i][1];
  80. m[i][3] = m[i][2] * m[i][1];
  81. }
  82. ans = inf;
  83. std::sort(ord, ord + n, [&](ul a, ul b){return rdeg[a] < rdeg[b];});
  84. search(0, (1 << n) - 1, 0, 0);
  85. if (ans != inf) {
  86. std::printf("%u\n", ans);
  87. } else {
  88. std::printf("-1\n");
  89. }
  90. }
  91. return 0;
  92. }

C、And and Pair

简单题

  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 mod = 1e9 + 7;
  8. const ul maxlen = 1e5;
  9. char s[maxlen + 2];
  10. ul plus(ul a, ul b)
  11. {
  12. return a + b < mod ? a + b : a + b - mod;
  13. }
  14. ul minus(ul a, ul b)
  15. {
  16. return a < b ? a + mod - b : a - b;
  17. }
  18. ul mul(ul a, ul b)
  19. {
  20. return ull(a) * ull(b) % mod;
  21. }
  22. int main()
  23. {
  24. std::scanf("%u", &T);
  25. for (ul Case = 1; Case <= T; ++Case) {
  26. ul tmp = 1;
  27. ul sum = 1;
  28. std::scanf("%s", s + 1);
  29. ul len = std::strlen(s + 1);
  30. for (ul i = len; i; --i) {
  31. if (s[i] == '1') {
  32. sum = plus(sum, tmp);
  33. tmp = mul(tmp, 3);
  34. } else {
  35. tmp = mul(tmp, 2);
  36. }
  37. }
  38. std::printf("%u\n", sum);
  39. }
  40. return 0;
  41. }

D、Bitwise Tree

用uint64_t f[2]来表示一个从的映射,当输入为的时候,输出的第位等于f[t >> i & 1] >> i。于是考虑映射复合的时候应该等于什么。那么有如下结果:
①对于:g[0] = f[0]; g[1] = f[0] & ~a ^ f[1] & a;
②对于:g[1] = f[1]; g[0] = f[0] & ~a ^ f[1] & a;
③对于:b = (f[0] ^ f[1]) & a; g[0] = f[0] ^ b; g[1] = f[1] ^ b;
于是可以完成一个映射和一个半截运算的复合,于是时间复杂度为

  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 uss = std::uint8_t;
  7. const ul maxn = 1e5;
  8. ul n;
  9. ul q;
  10. const ul maxq = 1e5;
  11. ull a[maxn + 1];
  12. ul totedge;
  13. ul totedge0;
  14. class edge_t {
  15. public:
  16. ul next = 0;
  17. ul to = 0;
  18. };
  19. ul s[maxn + 1];
  20. edge_t sons[maxn];
  21. edge_t sons0[maxn];
  22. ul head0[maxn + 1];
  23. ul head[maxn + 1];
  24. void addedge0(ul a, ul b)
  25. {
  26. ++totedge0;
  27. sons0[totedge0].to = b;
  28. sons0[totedge0].next = head0[a];
  29. head0[a] = totedge0;
  30. }
  31. void addedge(ul a, ul b)
  32. {
  33. ++totedge;
  34. sons[totedge].to = b;
  35. sons[totedge].next = head[a];
  36. head[a] = totedge;
  37. }
  38. const ull full = ~ull(0);
  39. ull tmpans[maxn + 1][3][2];
  40. ul tim;
  41. ul already[maxn + 1];
  42. ull ans[maxq + 1][3];
  43. class query_t {
  44. public:
  45. ul d = 0;
  46. ul u = 0;
  47. ul id = 0;
  48. };
  49. query_t querys[maxq + 1];
  50. ull f(ul s, ull a, ull b)
  51. {
  52. return s == 0 ? (a | b) : (s == 1 ? (a & b) : (a ^ b));
  53. }
  54. ul d, pos;
  55. void search0(ul curr)
  56. {
  57. for (ul eid = head0[curr]; eid; eid = sons0[eid].next) {
  58. ul next = sons0[eid].to;
  59. addedge(curr, next);
  60. search0(next);
  61. }
  62. }
  63. void deal(const ull from[], ul s, ull to[], ull a)
  64. {
  65. if (s == 0) {
  66. to[1] = from[1];
  67. to[0] = from[0] & ~a ^ from[1] & a;
  68. } else if (s == 1) {
  69. to[0] = from[0];
  70. to[1] = from[0] & ~a ^ from[1] & a;
  71. } else {
  72. ull b = (from[0] ^ from[1]) & a;
  73. to[0] = from[0] ^ b;
  74. to[1] = from[1] ^ b;
  75. }
  76. }
  77. ull calc(const ull f[], ull a)
  78. {
  79. return f[0] & ~a ^ f[1] & a;
  80. }
  81. void search(ul curr)
  82. {
  83. ull cn[2];
  84. ull tn[3][2];
  85. if (already[curr] == tim) {
  86. return;
  87. }
  88. already[curr] = tim;
  89. auto c = tmpans[curr];
  90. c[0][0] = 0;
  91. c[0][1] = 0;
  92. c[1][0] = ~ull(0);
  93. c[1][1] = ~ull(0);
  94. c[2][0] = 0;
  95. c[2][1] = 0;
  96. for (ul eid = head[curr]; eid; eid = sons[eid].next) {
  97. ul next = sons[eid].to;
  98. cn[0] = f(s[next], 0, a[next] + next * d);
  99. cn[1] = f(s[next], ~ull(0), a[next] + next * d);
  100. c[0][0] |= cn[0];
  101. c[0][1] |= cn[1];
  102. c[1][0] &= cn[0];
  103. c[1][1] &= cn[1];
  104. c[2][0] ^= cn[0];
  105. c[2][1] ^= cn[1];
  106. search(next);
  107. auto n = tmpans[next];
  108. for (ul i = 0; i <= 2; ++i) {
  109. deal(n[i], s[next], tn[i], a[next] + next * d);
  110. }
  111. c[0][0] |= tn[0][0];
  112. c[0][1] |= tn[0][1];
  113. c[1][0] &= tn[1][0];
  114. c[1][1] &= tn[1][1];
  115. c[2][0] ^= tn[2][0];
  116. c[2][1] ^= tn[2][1];
  117. }
  118. }
  119. int main()
  120. {
  121. std::scanf("%u%u", &n, &q);
  122. for (ul i = 1; i <= n; ++i) {
  123. std::scanf("%llu", &a[i]);
  124. }
  125. for (ul i = 2; i <= n; ++i) {
  126. ul f;
  127. std::scanf("%u%u", &f, &s[i]);
  128. addedge0(f, i);
  129. }
  130. search0(1);
  131. for (ul i = 1; i <= q; ++i) {
  132. std::scanf("%u%u", &querys[i].d, &querys[i].u);
  133. querys[i].id = i;
  134. }
  135. std::sort(querys + 1, querys + q + 1, [](const query_t& a, const query_t& b){return a.d < b.d;});
  136. for (ul i = 1, j = 1; i <= q; i = j) {
  137. for (j = i; j <= q && querys[j].d == querys[i].d; ++j);
  138. d = querys[i].d;
  139. ++tim;
  140. for (ul k = i; k != j; ++k) {
  141. ul u = querys[k].u;
  142. search(u);
  143. ull alpha = a[u] + u * d;
  144. auto c = tmpans[u];
  145. auto d = ans[querys[k].id];
  146. d[0] = calc(c[0], alpha);
  147. d[1] = calc(c[1], alpha);
  148. d[2] = calc(c[2], alpha);
  149. }
  150. }
  151. for (ul i = 1; i <= q; ++i) {
  152. std::printf("%llu %llu %llu\n", ans[i][0], ans[i][1], ans[i][2]);
  153. }
  154. return 0;
  155. }

E、Bob's Problem

简单题

  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, k, m;
  8. const ul maxm = 5e5;
  9. const ul maxn = 5e4;
  10. class edge_t {
  11. public:
  12. ul u = 0;
  13. ul v = 0;
  14. ul w = 0;
  15. ul c = 0;
  16. };
  17. edge_t edges[maxm + 1];
  18. ul fa[maxn + 1];
  19. ul rk[maxn + 1];
  20. ul tot;
  21. ul stack[maxm + 1];
  22. ul getfather(ul a)
  23. {
  24. return fa[a] == a ? a : fa[a] = getfather(fa[a]);
  25. }
  26. bool connect(ul a, ul b)
  27. {
  28. a = getfather(a);
  29. b = getfather(b);
  30. if (a == b) {
  31. return false;
  32. }
  33. if (rk[a] < rk[b]) {
  34. fa[a] = b;
  35. } else if (rk[a] > rk[b]) {
  36. fa[b] = a;
  37. } else {
  38. fa[a] = b;
  39. ++rk[b];
  40. }
  41. return true;
  42. }
  43. int main()
  44. {
  45. std::scanf("%u", &T);
  46. for (ul Case = 1; Case <= T; ++Case) {
  47. std::scanf("%u%u%u", &n, &m, &k);
  48. for (ul i = 1; i <= n; ++i) {
  49. rk[i] = 0;
  50. fa[i] = i;
  51. }
  52. for (ul i = 1; i <= m; ++i) {
  53. std::scanf("%u%u%u%u", &edges[i].u, &edges[i].v, &edges[i].w, &edges[i].c);
  54. }
  55. std::sort(edges + 1, edges + m + 1, [](const edge_t& a, const edge_t& b){return a.c != b.c ? a.c < b.c : a.w > b.w;});
  56. tot = 0;
  57. ull sum = 0;
  58. for (ul i = 1; i <= m; ++i) {
  59. if (edges[i].c) {
  60. if (!k) {
  61. break;
  62. }
  63. if (connect(edges[i].u, edges[i].v)) {
  64. --n;
  65. --k;
  66. sum += edges[i].w;
  67. } else {
  68. ++tot;
  69. stack[tot] = i;
  70. }
  71. } else {
  72. n -= connect(edges[i].u, edges[i].v);
  73. sum += edges[i].w;
  74. }
  75. }
  76. if (n != 1) {
  77. std::printf("-1\n");
  78. continue;
  79. }
  80. for (ul i = 1; i <= k && i <= tot; ++i) {
  81. sum += edges[stack[i]].w;
  82. }
  83. std::printf("%llu\n", sum);
  84. }
  85. return 0;
  86. }

F、Dynamic Suffix Array

考虑整个字符串的后缀树,然后求出后缀树的深搜序,接着,每当砍掉后边一部分,那么一个后缀在后缀树上就会移动到其原始位置的某个祖先那里,所以只需要随着长度减小维护这个即可。注意字符串是随机的,那么公共子串的长度一定不长,这意味着任何节点到根的路径上的节点数不多。再注意到一点,任何两个存在的后缀在长度减小的过程中一定不会处于同一个节点上,请自己证明。

  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 q;
  7. const ul maxq = 1e6;
  8. class query_t {
  9. public:
  10. ul len = 0;
  11. ul k = 0;
  12. ul ans = 0;
  13. };
  14. ul len;
  15. ul tot;
  16. char str[2];
  17. char s[maxq + 1];
  18. query_t querys[maxq + 1];
  19. class sam_t {
  20. public:
  21. ul las;
  22. class node {
  23. public:
  24. ul ch[26];
  25. ul len = 0;
  26. ul fa = 0;
  27. node() {
  28. std::memset(ch, 0, sizeof(ch));
  29. }
  30. };
  31. std::vector<node> st = std::vector<node>(maxq + maxq);
  32. void add(ul c)
  33. {
  34. ul p = las;
  35. ul np = las = st.size();
  36. st.push_back(node());
  37. st[np].len = st[p].len + 1;
  38. for ( ; p && !st[p].ch[c]; p = st[p].fa) {
  39. st[p].ch[c] = np;
  40. }
  41. if (!p) {
  42. st[np].fa = 1;
  43. } else {
  44. ul q = st[p].ch[c];
  45. if (st[q].len == st[p].len + 1) {
  46. st[np].fa = q;
  47. } else {
  48. ul nq = st.size();
  49. st.push_back(node());
  50. st[nq] = st[q];
  51. st[nq].len = st[p].len + 1;
  52. st[q].fa = st[np].fa = nq;
  53. for ( ; p && st[p].ch[c] == q; p = st[p].fa) {
  54. st[p].ch[c] = nq;
  55. }
  56. }
  57. }
  58. }
  59. void init() {
  60. las = 1;
  61. st.resize(0);
  62. st.resize(2);
  63. }
  64. };
  65. sam_t sam;
  66. class listnode {
  67. public:
  68. ul next = 0;
  69. ul val = 0;
  70. };
  71. ul listtot;
  72. listnode listnodes[maxq + maxq];
  73. ul listremain;
  74. ul listrestack[maxq + maxq];
  75. void push_front(ul& x, ul v)
  76. {
  77. ul tmp;
  78. if (listremain) {
  79. tmp = listrestack[listremain];
  80. --listremain;
  81. } else {
  82. ++listtot;
  83. tmp = listtot;
  84. }
  85. listnodes[tmp].val = v;
  86. listnodes[tmp].next = x;
  87. x = tmp;
  88. }
  89. void pop_front(ul& x)
  90. {
  91. ++listremain;
  92. listrestack[listremain] = x;
  93. x = listnodes[x].next;
  94. }
  95. void moveto(ul& y, ul& x)
  96. {
  97. ul z = listnodes[y].next;
  98. listnodes[y].next = x;
  99. x = y;
  100. y = z;
  101. }
  102. ul pos[maxq + maxq];
  103. void sort(ul len, ul& x, bool dir)
  104. {
  105. if (listnodes[x].next == 0) {
  106. return;
  107. }
  108. ul y = x, b = listnodes[x].next;
  109. while (listnodes[b].next) {
  110. y = listnodes[y].next;
  111. b = listnodes[b].next;
  112. b = listnodes[b].next;
  113. }
  114. ul py = y;
  115. y = listnodes[y].next;
  116. listnodes[py].next = 0;
  117. sort(len, x, !dir);
  118. sort(len, y, !dir);
  119. ul z = 0;
  120. while (x || y) {
  121. if (x && y) {
  122. if ((s[pos[listnodes[x].val] + len] > s[pos[listnodes[y].val] + len]) == dir) {
  123. moveto(x, z);
  124. } else {
  125. moveto(y, z);
  126. }
  127. } else if (x) {
  128. moveto(x, z);
  129. } else {
  130. moveto(y, z);
  131. }
  132. }
  133. x = z;
  134. }
  135. ul sons[maxq + maxq];
  136. ul at[maxq + 1];
  137. ul dfn[maxq + maxq];
  138. ul tim;
  139. void search1(ul curr)
  140. {
  141. for (ul eid = sons[curr]; eid; eid = listnodes[eid].next) {
  142. ul next = listnodes[eid].val;
  143. search1(next);
  144. pos[curr] = std::max(pos[curr], pos[next]);
  145. }
  146. }
  147. void search2(ul curr)
  148. {
  149. ++tim;
  150. dfn[curr] = tim;
  151. sort(sam.st[curr].len, sons[curr], 1);
  152. while (sons[curr]) {
  153. ul next = listnodes[sons[curr]].val;
  154. pop_front(sons[curr]);
  155. search2(next);
  156. }
  157. }
  158. ul stack[maxq + 1];
  159. const ul sz = 1 << 21;
  160. ul tree[sz << 1];
  161. void change(ul pos, ul x)
  162. {
  163. for (tree[pos |= sz] += x, pos >>= 1; pos; pos >>= 1) {
  164. tree[pos] = tree[pos << 1] + tree[pos << 1 | 1];
  165. }
  166. }
  167. ul getsum(ul l, ul r)
  168. {
  169. ul ret = 0;
  170. for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {
  171. if (~l & 1) {
  172. ret += tree[l ^ 1];
  173. }
  174. if (r & 1) {
  175. ret += tree[r ^ 1];
  176. }
  177. }
  178. return ret;
  179. }
  180. int main()
  181. {
  182. std::scanf("%u", &q);
  183. for (ul i = 1; i <= q; ++i) {
  184. ul t;
  185. std::scanf("%u", &t);
  186. if (t == 1) {
  187. std::scanf("%s", str);
  188. ++len;
  189. s[len] = str[0];
  190. } else {
  191. ++tot;
  192. std::scanf("%u", &querys[tot].k);
  193. querys[tot].len = len;
  194. }
  195. }
  196. sam.init();
  197. for (ul i = len; i >= 1; --i) {
  198. sam.add(s[i] - 'a');
  199. at[i] = sam.las;
  200. pos[sam.las] = i;
  201. }
  202. for (ul i = 2; i != sam.st.size(); ++i) {
  203. push_front(sons[sam.st[i].fa], i);
  204. }
  205. pos[1] = len + 1;
  206. search1(1);
  207. search2(1);
  208. for (ul i = 1; i <= len; ++i) {
  209. push_front(stack[i + sam.st[sam.st[at[i]].fa].len - 1], i);
  210. change(dfn[at[i]], 1);
  211. }
  212. ul currlen = len;
  213. for (ul i = tot; i; --i) {
  214. while (currlen > querys[i].len) {
  215. --currlen;
  216. while (stack[currlen]) {
  217. ul t = listnodes[stack[currlen]].val;
  218. pop_front(stack[currlen]);
  219. change(dfn[at[t]], -1);
  220. at[t] = sam.st[at[t]].fa;
  221. if (at[t] != 1) {
  222. change(dfn[at[t]], 1);
  223. push_front(stack[t + sam.st[sam.st[at[t]].fa].len - 1], t);
  224. }
  225. }
  226. }
  227. querys[i].ans = getsum(1, dfn[at[querys[i].k]]);
  228. }
  229. for (ul i = 1; i <= tot; ++i) {
  230. std::printf("%u\n", querys[i].ans);
  231. }
  232. return 0;
  233. }

G、Eating Plan

模数的最大质因子为

  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. const ul maxtot = 2802;
  8. ul tot;
  9. const ul t = 998857459;
  10. ul fac[maxtot + 1];
  11. ul val[maxtot + 1];
  12. ul pos[maxtot + 1];
  13. ul tot2;
  14. std::pair<ul, ul> stack[(maxtot * (maxtot + 1) >> 1) + 1];
  15. ul tot3;
  16. std::pair<ul, ul> stack2[(maxtot * (maxtot + 1) >> 1) + 1];
  17. int main()
  18. {
  19. fac[0] = 1;
  20. for (ul i = 1; i <= maxtot; ++i) {
  21. fac[i] = ull(fac[i - 1]) * ull(i) % t;
  22. }
  23. std::scanf("%u%u", &n, &m);
  24. for (ul i = 1; i <= n; ++i) {
  25. ul a;
  26. std::scanf("%u", &a);
  27. if (a > maxtot) {
  28. continue;
  29. }
  30. ++tot;
  31. val[tot] = fac[a];
  32. pos[tot] = i;
  33. }
  34. for (ul i = 1; i <= tot; ++i) {
  35. ul sum = 0;
  36. for (ul j = i; j <= tot; ++j) {
  37. sum = sum + val[j] < t ? sum + val[j] : sum + val[j] - t;
  38. ++tot2;
  39. stack[tot2].first = sum;
  40. stack[tot2].second = pos[j] - pos[i] + 1;
  41. }
  42. }
  43. std::sort(stack + 1, stack + tot2 + 1, [](const std::pair<ul, ul>& a, const std::pair<ul, ul>& b){return a.first != b.first ? a.first < b.first : a.second > b.second;});
  44. for (ul i = 1; i <= tot2; ++i) {
  45. while (tot3 && stack2[tot3].second >= stack[i].second) {
  46. --tot3;
  47. }
  48. ++tot3;
  49. stack2[tot3] = stack[i];
  50. }
  51. for (ul i = 1; i <= m; ++i) {
  52. ul k;
  53. std::scanf("%u", &k);
  54. auto it = std::lower_bound(stack2 + 1, stack2 + tot3 + 1, std::pair<ul, ul>(k, 0)) - stack2;
  55. if (it == tot3 + 1) {
  56. std::printf("-1\n");
  57. } else {
  58. std::printf("%u\n", stack2[it].second);
  59. }
  60. }
  61. return 0;
  62. }

H、Powers of Two

的开头正好是当且仅当:。注意只有当是零的时候才有可能出现“刚好相等”的问题,于是将的情况单独处理,那么该表达式的大于和大于等于可以换一下。故该问题实际就是最小化满足以下条件的

二分并类欧几里得即可。

  1. def getsum(a, b, c, n):
  2. if n <= 0 :
  3. return 0
  4. if a >= c or b >= c :
  5. return getsum(a % c, b % c, c, n) + n * (n + 1) // 2 * (a // c) + n * (b // c)
  6. if a == 0 :
  7. return 0
  8. if a * n + b < c :
  9. return 0
  10. return n * ((a * n + b) // c) - (c - b - 1) // a - getsum(c, c - b - 1, a, (a * n + b) // c - 1)
  11. import decimal
  12. from decimal import Decimal
  13. decimal.getcontext().prec = 1000
  14. two = Decimal("2")
  15. ten = Decimal("10")
  16. instr = input()
  17. p = int(instr.split(' ')[0])
  18. p0 = Decimal(p);
  19. p1 = Decimal(p + 1)
  20. k = int(instr.split(' ')[1])
  21. for i in range(0, 101) :
  22. if p == 2 ** i :
  23. k = k - 1
  24. alpha = 500
  25. a = int(ten.ln() / two.ln() * (10 ** alpha))
  26. c = 10 ** alpha
  27. b1 = int(p1.ln() / two.ln() * (10 ** alpha))
  28. b0 = int(p0.ln() / two.ln() * (10 ** alpha))
  29. l = -1
  30. r = 161173615628205990885158576527746324
  31. mid = 0
  32. while l + 1 != r :
  33. mid = (l + r) // 2
  34. if getsum(a, b1, c, mid) - getsum(a, b0, c, mid) >= k :
  35. r = mid
  36. else :
  37. l = mid
  38. if r == 0 :
  39. for i in range(0, 101):
  40. if p == 2 ** i :
  41. print(i)
  42. else :
  43. print((r * a + b0) // c + 1)

I、

J、Summon

简单题

  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. ul n, m;
  36. const ul maxn = 1e5;
  37. std::vector<bool> ban(256, false);
  38. ul trans[64][64];
  39. void mul(const ul a[][64], const ul b[][64], ul c[][64])
  40. {
  41. for (ul i = 0; i != 64; ++i) {
  42. for (ul j = 0; j != 64; ++j) {
  43. c[i][j] = 0;
  44. for (ul k = 0; k != 64; ++k) {
  45. c[i][j] = plus(c[i][j], mul(a[i][k], b[k][j]));
  46. }
  47. }
  48. }
  49. }
  50. void pow(const ul ina[][64], ul b, ul c[][64])
  51. {
  52. static ul a[64][64];
  53. static ul tmp[64][64];
  54. std::memcpy(a, ina, sizeof(ul) << 12);
  55. for (ul i = 0; i != 64; ++i) {
  56. for (ul j = 0; j != 64; ++j) {
  57. c[i][j] = i == j;
  58. }
  59. }
  60. while (b) {
  61. if (b & 1) {
  62. mul(a, c, tmp);
  63. std::memcpy(c, tmp, sizeof(ul) << 12);
  64. }
  65. b >>= 1;
  66. mul(a, a, tmp);
  67. std::memcpy(a, tmp, sizeof(ul) << 12);
  68. }
  69. }
  70. ul totprime;
  71. ul prime[maxn + 1];
  72. std::vector<bool> notprime(maxn + 1, false);
  73. ul phi[maxn + 1];
  74. ul ans = 0;
  75. ul curr[64][64];
  76. bool able[64][64];
  77. int main()
  78. {
  79. phi[1] = 1;
  80. for (ul i = 2; i <= maxn; ++i) {
  81. if (!notprime[i]) {
  82. ++totprime;
  83. prime[totprime] = i;
  84. phi[i] = i - 1;
  85. }
  86. for (ul pid = 1; pid <= totprime; ++pid) {
  87. ul p = prime[pid];
  88. if (i * p > maxn) {
  89. break;
  90. }
  91. notprime[i * p] = true;
  92. if (i % p == 0) {
  93. phi[i * p] = phi[i] * p;
  94. break;
  95. } else {
  96. phi[i * p] = phi[i] * (p - 1);
  97. }
  98. }
  99. }
  100. std::scanf("%u%u", &n, &m);
  101. for (ul i = 1; i <= m; ++i) {
  102. ul a, b, c, d;
  103. std::scanf("%u%u%u%u", &a, &b, &c, &d);
  104. ban[a << 0 | b << 2 | c << 4 | d << 6] = true;
  105. }
  106. for (ul from = 0; from != 64; ++from) {
  107. for (ul a : {0, 1, 2, 3}) {
  108. if (ban[from << 2 | a]) {
  109. continue;
  110. }
  111. trans[from][(from << 2 | a) & 63] = 1;
  112. }
  113. }
  114. for (ul i = 0; i != 64; ++i) {
  115. for (ul j = 0; j != 64; ++j) {
  116. able[i][j] = !(ban[(j << 2 | i >> 4) & 255] || ban[(j << 4 | i >> 2) & 255] || ban[(j << 6 | i >> 0) & 255]);
  117. }
  118. }
  119. for (ul d = 1; d <= n; ++d) {
  120. if (n % d != 0) {
  121. continue;
  122. }
  123. ul tmp = 0;
  124. if (d == 1) {
  125. for (ul i = 0; i != 4; ++i) {
  126. if (!ban[i << 0 | i << 2 | i << 4 | i << 6]) {
  127. tmp = plus(tmp, 1);
  128. }
  129. }
  130. } else if (d == 2) {
  131. for (ul i = 0; i != 16; ++i) {
  132. if (!ban[i << 0 | i << 4] && !ban[(i >> 2 | i << 2 | i << 6) & 255]) {
  133. tmp = plus(tmp, 1);
  134. }
  135. }
  136. } else {
  137. pow(trans, d - 3, curr);
  138. for (ul i = 0; i != 64; ++i) {
  139. for (ul j = 0; j != 64; ++j) {
  140. if (able[i][j]) {
  141. tmp = plus(tmp, curr[i][j]);
  142. }
  143. }
  144. }
  145. }
  146. ans = plus(ans, mul(phi[n / d], tmp));
  147. }
  148. std::printf("%u\n", mul(ans, inverse(n)));
  149. return 0;
  150. }

K、Tree

启发式合并套树套树。
注意, is up to 是指

  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, k;
  8. ul v[maxn + 1];
  9. class listnode {
  10. public:
  11. ul val = 0;
  12. ul next = 0;
  13. };
  14. ul listtot;
  15. listnode listnodes[maxn];
  16. void push_front(ul& x, ul v)
  17. {
  18. ++listtot;
  19. listnodes[listtot].val = v;
  20. listnodes[listtot].next = x;
  21. x = listtot;
  22. }
  23. ul sons[maxn + 1];
  24. std::mt19937_64 rnd;
  25. class node {
  26. public:
  27. ul key = 0;
  28. ul val = 0;
  29. ul cnt = 0;
  30. ul sum = 0;
  31. ul lson = 0;
  32. ul rson = 0;
  33. ull weight = 0;
  34. node() {
  35. weight = rnd();
  36. }
  37. };
  38. ul tot = 0;
  39. ul remain = 0;
  40. ul stack[1 << 22];
  41. node tree[1 << 22];
  42. void update(ul x)
  43. {
  44. tree[x].sum = tree[x].cnt + tree[tree[x].lson].sum + tree[tree[x].rson].sum;
  45. }
  46. void lrotate(ul& x)
  47. {
  48. ul y = tree[x].rson;
  49. tree[x].rson = tree[y].lson;
  50. tree[y].lson = x;
  51. update(x);
  52. update(y);
  53. x = y;
  54. }
  55. void rrotate(ul& x)
  56. {
  57. ul y = tree[x].lson;
  58. tree[x].lson = tree[y].rson;
  59. tree[y].rson = x;
  60. update(x);
  61. update(y);
  62. x = y;
  63. }
  64. ul insert(ul& x, ul key, ul val)
  65. {
  66. if (!x) {
  67. if (remain) {
  68. x = stack[remain];
  69. --remain;
  70. } else {
  71. ++tot;
  72. x = tot;
  73. }
  74. tree[x] = node();
  75. tree[x].key = key;
  76. tree[x].val = val;
  77. tree[x].cnt = 1;
  78. update(x);
  79. return x;
  80. }
  81. if (tree[x].key == key) {
  82. ++tree[x].cnt;
  83. update(x);
  84. return x;
  85. } else if (tree[x].key < key) {
  86. ul ret = insert(tree[x].rson, key, val);
  87. update(x);
  88. if (tree[x].weight < tree[tree[x].rson].weight) {
  89. lrotate(x);
  90. }
  91. return ret;
  92. } else if (tree[x].key > key) {
  93. ul ret = insert(tree[x].lson, key, val);
  94. update(x);
  95. if (tree[x].weight < tree[tree[x].lson].weight) {
  96. rrotate(x);
  97. }
  98. return ret;
  99. }
  100. }
  101. ul find(ul x, ul key)
  102. {
  103. if (!x) {
  104. return 0;
  105. }
  106. if (tree[x].key == key) {
  107. return x;
  108. } else if (tree[x].key < key) {
  109. return find(tree[x].rson, key);
  110. } else {
  111. return find(tree[x].lson, key);
  112. }
  113. }
  114. void kill(ul x)
  115. {
  116. ++remain;
  117. stack[remain] = x;
  118. }
  119. ul getsum(ul x, ul t)
  120. {
  121. if (!x) {
  122. return 0;
  123. }
  124. if (tree[x].key > t) {
  125. return getsum(tree[x].lson, t);
  126. } else if (tree[x].key == t) {
  127. return tree[x].sum - tree[tree[x].rson].sum;
  128. } else if (tree[x].key < t) {
  129. return tree[x].sum - tree[tree[x].rson].sum + getsum(tree[x].rson, t);
  130. }
  131. }
  132. ul tot2;
  133. ul stack2[maxn + maxn + 1];
  134. ul tot3;
  135. ul stack3[maxn + maxn + 1];
  136. ull ans = 0;
  137. void search(ul curr, ul depth, ul& blob, ul& sz)
  138. {
  139. blob = 0;
  140. sz = 0;
  141. for (ul eid = sons[curr]; eid; eid = listnodes[eid].next) {
  142. ul next = listnodes[eid].val;
  143. ul nextblob;
  144. ul nextsz;
  145. search(next, depth + 1, nextblob, nextsz);
  146. if (sz < nextsz) {
  147. std::swap(blob, nextblob);
  148. }
  149. sz += nextsz;
  150. ++tot2;
  151. stack2[tot2] = nextblob;
  152. while (tot2) {
  153. ul it2 = stack2[tot2];
  154. --tot2;
  155. if (!it2) {
  156. continue;
  157. }
  158. ++tot2;
  159. stack2[tot2] = tree[it2].rson;
  160. ++tot2;
  161. stack2[tot2] = tree[it2].lson;
  162. auto currit2 = find(blob, v[curr] + v[curr] - tree[it2].key);
  163. if (!currit2) {
  164. continue;
  165. }
  166. ++tot3;
  167. stack3[tot3] = tree[it2].val;
  168. while (tot3) {
  169. ul it3 = stack3[tot3];
  170. --tot3;
  171. if (!it3) {
  172. continue;
  173. }
  174. ++tot3;
  175. stack3[tot3] = tree[it3].rson;
  176. ++tot3;
  177. stack3[tot3] = tree[it3].lson;
  178. ull data = getsum(tree[currit2].val, std::max(depth + depth + k, tree[it3].key) - tree[it3].key);
  179. ans += 2 * tree[it3].cnt * data;
  180. }
  181. }
  182. ++tot2;
  183. stack2[tot2] = nextblob;
  184. while (tot2) {
  185. ul it2 = stack2[tot2];
  186. --tot2;
  187. if (!it2) {
  188. continue;
  189. }
  190. ++tot2;
  191. stack2[tot2] = tree[it2].rson;
  192. ++tot2;
  193. stack2[tot2] = tree[it2].lson;
  194. auto currit2 = insert(blob, tree[it2].key, 0);
  195. ++tot3;
  196. stack3[tot3] = tree[it2].val;
  197. while (tot3) {
  198. ul it3 = stack3[tot3];
  199. --tot3;
  200. if (!it3) {
  201. continue;
  202. }
  203. ++tot3;
  204. stack3[tot3] = tree[it3].rson;
  205. ++tot3;
  206. stack3[tot3] = tree[it3].lson;
  207. for (ul i = 1; i <= tree[it3].cnt; ++i) {
  208. insert(tree[currit2].val, tree[it3].key, 0);
  209. }
  210. kill(it3);
  211. }
  212. kill(it2);
  213. }
  214. }
  215. ++sz;
  216. auto currit2 = insert(blob, v[curr], 0);
  217. insert(tree[currit2].val, depth, 0);
  218. }
  219. int main()
  220. {
  221. rnd.seed(std::time(0));
  222. std::scanf("%u%u", &n, &k);
  223. for (ul i = 1; i <= n; ++i) {
  224. std::scanf("%u", &v[i]);
  225. }
  226. for (ul i = 2; i <= n; ++i) {
  227. ul f;
  228. std::scanf("%u", &f);
  229. push_front(sons[f], i);
  230. }
  231. ul blob, sz;
  232. search(1, 0, blob, sz);
  233. std::printf("%llu\n", ans);
  234. return 0;
  235. }

L、Who is the Champion

简单题

  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 = 100;
  7. ul n;
  8. ul a[maxn + 1][maxn + 1];
  9. std::pair<ul, li> score[maxn + 1];
  10. int main()
  11. {
  12. std::scanf("%u", &n);
  13. for (ul i = 1; i <= n; ++i) {
  14. for (ul j = 1; j <= n; ++j) {
  15. std::scanf("%u", &a[i][j]);
  16. }
  17. }
  18. for (ul i = 1; i <= n; ++i) {
  19. for (ul j = 1; j <= n; ++j) {
  20. if (i == j) {
  21. continue;
  22. }
  23. if (a[i][j] > a[j][i]) {
  24. score[i].first += 3;
  25. } else if (a[i][j] == a[j][i]) {
  26. score[i].first += 1;
  27. }
  28. score[i].second += a[i][j];
  29. score[i].second -= a[j][i];
  30. }
  31. }
  32. ul mxid;
  33. ul mxcnt;
  34. std::pair<ul, li> mx(0, -1e9);
  35. for (ul i = 1; i <= n; ++i) {
  36. if (mx < score[i]) {
  37. mxid = i;
  38. mxcnt = 0;
  39. mx = score[i];
  40. }
  41. if (mx == score[i]) {
  42. ++mxcnt;
  43. }
  44. }
  45. if (mxcnt == 1) {
  46. std::printf("%u\n", mxid);
  47. } else {
  48. std::printf("play-offs\n");
  49. }
  50. return 0;
  51. }

M、XOR Sum

首先

于是
每一个表达式都可以插值得到答案。

  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 = 1e9 + 7;
  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. ul pow(ul a, ul b)
  36. {
  37. ul ret = 1;
  38. while (b) {
  39. if (b & 1) {
  40. ret = mul(ret, a);
  41. }
  42. a = mul(a, a);
  43. b >>= 1;
  44. }
  45. return ret;
  46. }
  47. ul t;
  48. ll x, y;
  49. const ul maxt = 1e5;
  50. ul f0(ul q)
  51. {
  52. ul fourq = mul(4, q);
  53. if (fourq == 1) {
  54. return t;
  55. }
  56. return mul(minus(pow(fourq, t + 1), fourq), inverse(minus(fourq, 1)));
  57. }
  58. ul f1(ul q)
  59. {
  60. return t;
  61. }
  62. ul f2(ul q)
  63. {
  64. ul fourqp2 = plus(mul(4, q), 2);
  65. if (fourqp2 == 1) {
  66. return plus(t, 1);
  67. }
  68. return plus(mul(minus(pow(fourqp2, t + 1), fourqp2), inverse(minus(fourqp2, 1))), 1);
  69. }
  70. ul f3(ul q)
  71. {
  72. return mul(minus(plus(mul(2, t), pow(minus(0, 1), t)), 1), inverse(4));
  73. }
  74. ul fac[maxt + 2];
  75. ul fiv[maxt + 2];
  76. ul facm[maxt + 2];
  77. ul fivm[maxt + 2];
  78. ul calc(const ul g[], ul deg, ul x)
  79. {
  80. static ul xmjpre[maxt + 3];
  81. static ul xmjsuf[maxt + 3];
  82. xmjpre[0] = x;
  83. for (ul j = 1; j <= deg; ++j) {
  84. xmjpre[j] = mul(xmjpre[j - 1], minus(x, j));
  85. }
  86. xmjsuf[deg + 1] = 1;
  87. for (ul j = deg; ~j; --j) {
  88. xmjsuf[j] = mul(xmjsuf[j + 1], minus(x, j));
  89. }
  90. ul ans = 0;
  91. for (ul i = 1; i <= deg; ++i) {
  92. ans = plus(ans, mul(g[i], mul(mul(xmjpre[i - 1], xmjsuf[i + 1]), mul(fiv[i], fivm[deg - i]))));
  93. }
  94. return ans;
  95. }
  96. ul getans(ll lq, ll rq, ul (*f)(ul), ul deg)
  97. {
  98. static ul g[maxt + 2];
  99. g[0] = 0;
  100. for (ul i = 1; i <= deg; ++i) {
  101. g[i] = plus(g[i - 1], f((lq + i - 1) % mod));
  102. }
  103. return calc(g, deg, (rq - lq + 1) % mod);
  104. }
  105. ll ceil(ll a)
  106. {
  107. return a > 0 ? (a + 3) / 4 : a / 4;
  108. }
  109. ll floor(ll a)
  110. {
  111. return a < 0 ? (a - 3) / 4 : a / 4;
  112. }
  113. int main()
  114. {
  115. fac[0] = 1;
  116. facm[0] = 1;
  117. for (ul i = 1; i <= maxt + 1; ++i) {
  118. fac[i] = mul(fac[i - 1], i);
  119. facm[i] = mul(facm[i - 1], minus(0, i));
  120. }
  121. fiv[maxt + 1] = inverse(fac[maxt + 1]);
  122. fivm[maxt + 1] = inverse(facm[maxt + 1]);
  123. for (ul i = maxt + 1; i; --i) {
  124. fiv[i - 1] = mul(fiv[i], i);
  125. fivm[i - 1] = mul(fivm[i], minus(0, i));
  126. }
  127. std::scanf("%u%lld%lld", &t, &x, &y);
  128. std::printf("%u\n", plus(plus(getans(ceil(x), floor(y), f0, t + 1), getans(ceil(x - 1), floor(y - 1), f1, 1)), plus(getans(ceil(x - 2), floor(y - 2), f2, t + 1), getans(ceil(x - 3), floor(y - 3), f3, 1))));
  129. return 0;
  130. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注