D - Cutting Woods

记录每一个切割点,每次求前驱后驱就好了,注意简单判断一下开闭区间。

考场上采用的 FHQ_Treap 无脑莽。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. using namespace std;
  4. typedef long long LL;
  5. LL Max(LL x, LL y) { return x > y ? x : y; }
  6. LL Min(LL x, LL y) { return x < y ? x : y; }
  7. LL Abs(LL x) { return x < 0 ? -x : x; }
  8. int read() {
  9. int k = 1, x = 0;
  10. char s = getchar();
  11. while (s < '0' || s > '9') {
  12. if (s == '-')
  13. k = -1;
  14. s = getchar();
  15. }
  16. while (s >= '0' && s <= '9') {
  17. x = (x << 3) + (x << 1) + s - '0';
  18. s = getchar();
  19. }
  20. return x * k;
  21. }
  22. LL read_LL() {
  23. int k = 1;
  24. LL x = 0;
  25. char s = getchar();
  26. while (s < '0' || s > '9') {
  27. if (s == '-')
  28. k = -1;
  29. s = getchar();
  30. }
  31. while (s >= '0' && s <= '9') {
  32. x = (x << 3) + (x << 1) + s - '0';
  33. s = getchar();
  34. }
  35. return x * k;
  36. }
  37. void write(LL x) {
  38. if (x < 0) {
  39. putchar('-');
  40. x = -x;
  41. }
  42. if (x > 9)
  43. write(x / 10);
  44. putchar(x % 10 + '0');
  45. }
  46. void print(LL x, char s) {
  47. write(x);
  48. putchar(s);
  49. }
  50. // Fhq-Treap
  51. const int MAXN = 2e5 + 5;
  52. struct Fhq_Treap {
  53. struct Fhq_Node {
  54. int l, r, val, key, size;
  55. #define lson tr[p].l
  56. #define rson tr[p].r
  57. Fhq_Node() {}
  58. Fhq_Node(int L, int R, int Val, int Key, int Size) {
  59. l = L;
  60. r = R;
  61. val = Val;
  62. key = Key;
  63. size = Size;
  64. }
  65. } tr[MAXN];
  66. int tot, root;
  67. Fhq_Treap() {
  68. tot = 0, root = 0;
  69. }
  70. int Get(int val) {
  71. tr[++tot] = Fhq_Node(0, 0, val, rand(), 1);
  72. return tot;
  73. }
  74. void Push_Up(int p) { tr[p].size = tr[lson].size + tr[rson].size + 1; }
  75. void Split(int p, int val, int &x, int &y) {
  76. if (!p) {
  77. x = 0, y = 0;
  78. return;
  79. }
  80. if (tr[p].val <= val) {
  81. x = p;
  82. Split(rson, val, rson, y);
  83. } else {
  84. y = p;
  85. Split(lson, val, x, lson);
  86. }
  87. Push_Up(p);
  88. }
  89. int Merge(int x, int y) {
  90. if (!x || !y)
  91. return x + y;
  92. if (tr[x].key <= tr[y].key) {
  93. tr[x].r = Merge(tr[x].r, y);
  94. Push_Up(x);
  95. return x;
  96. } else {
  97. tr[y].l = Merge(x, tr[y].l);
  98. Push_Up(y);
  99. return y;
  100. }
  101. }
  102. void Insert(int val) {
  103. int x, y;
  104. Split(root, val, x, y);
  105. root = Merge(Merge(x, Get(val)), y);
  106. }
  107. void Delete(int val) {
  108. int x, y, z;
  109. Split(root, val, x, z);
  110. Split(x, val - 1, x, y);
  111. y = Merge(tr[y].l, tr[y].r);
  112. root = Merge(Merge(x, y), z);
  113. }
  114. int Get_Rank(int val) {
  115. int x, y, ret;
  116. Split(root, val - 1, x, y);
  117. ret = tr[x].size + 1;
  118. root = Merge(x, y);
  119. return ret;
  120. }
  121. int Get_Val(int Rank) {
  122. int p = root;
  123. while (p) {
  124. if (tr[lson].size + 1 == Rank)
  125. return tr[p].val;
  126. else if (Rank <= tr[lson].size)
  127. p = lson;
  128. else {
  129. Rank -= (tr[lson].size + 1);
  130. p = rson;
  131. }
  132. }
  133. return 0;
  134. }
  135. int Get_Pre(int val) {
  136. int x, y, p;
  137. Split(root, val - 1, x, y);
  138. p = x;
  139. while (rson) p = rson;
  140. int ret = tr[p].val;
  141. root = Merge(x, y);
  142. return ret;
  143. }
  144. int Get_Next(int val) {
  145. int x, y, p;
  146. Split(root, val, x, y);
  147. p = y;
  148. while (lson) p = lson;
  149. int ret = tr[p].val;
  150. root = Merge(x, y);
  151. return ret;
  152. }
  153. #undef lson
  154. #undef rson
  155. } tree;
  156. int main() {
  157. int l = read(), q = read();
  158. tree.Insert(0);
  159. tree.Insert(l);
  160. for(int i = 1, opt, x; i <= q; i++) {
  161. opt = read(), x = read();
  162. if(opt == 1)
  163. tree.Insert(x);
  164. else
  165. print(tree.Get_Next(x) - tree.Get_Pre(x), '\n');
  166. }
  167. return 0;
  168. }

E - Sorting Queries

将所有的插入操作先存进一个临时序列。

在遇到排序操作时再处理这些序列里的元素。

具体来说就是直接丢进优先队列。也可以学我赛时直接 copy D 的 code 来改。

  1. #include <queue>
  2. #include <cstdio>
  3. using namespace std;
  4. typedef long long LL;
  5. LL Max(LL x, LL y) { return x > y ? x : y; }
  6. LL Min(LL x, LL y) { return x < y ? x : y; }
  7. LL Abs(LL x) { return x < 0 ? -x : x; }
  8. int read() {
  9. int k = 1, x = 0;
  10. char s = getchar();
  11. while (s < '0' || s > '9') {
  12. if (s == '-')
  13. k = -1;
  14. s = getchar();
  15. }
  16. while (s >= '0' && s <= '9') {
  17. x = (x << 3) + (x << 1) + s - '0';
  18. s = getchar();
  19. }
  20. return x * k;
  21. }
  22. LL read_LL() {
  23. int k = 1;
  24. LL x = 0;
  25. char s = getchar();
  26. while (s < '0' || s > '9') {
  27. if (s == '-')
  28. k = -1;
  29. s = getchar();
  30. }
  31. while (s >= '0' && s <= '9') {
  32. x = (x << 3) + (x << 1) + s - '0';
  33. s = getchar();
  34. }
  35. return x * k;
  36. }
  37. void write(LL x) {
  38. if (x < 0) {
  39. putchar('-');
  40. x = -x;
  41. }
  42. if (x > 9)
  43. write(x / 10);
  44. putchar(x % 10 + '0');
  45. }
  46. void print(LL x, char s) {
  47. write(x);
  48. putchar(s);
  49. }
  50. const int MAXN = 2e5 + 5;
  51. int num[MAXN], len = 0, tot = 1;
  52. priority_queue<int, vector<int>, greater<int> > q;
  53. int main() {
  54. int n = read();
  55. for(int i = 1, opt; i <= n; i++) {
  56. opt = read();
  57. if(opt == 1) {
  58. int x = read();
  59. num[++len] = x;
  60. }
  61. else if(opt == 2) {
  62. if(!q.empty()) {
  63. print(q.top(), '\n');
  64. q.pop();
  65. }
  66. else {
  67. print(num[tot], '\n');
  68. tot++;
  69. }
  70. }
  71. else {
  72. for(int i = tot; i <= len; i++)
  73. q.push(num[i]);
  74. tot = 1, len = 0;
  75. }
  76. }
  77. return 0;
  78. }

F - Make Pair

小清新的区间 dp 题。

相邻删除这样的操作就应该往区间 dp 上去想。

定义 \(f(i, j)\) 表示将区间 \([i, j]\) 匹配完的方案数,显然需要满足 \(2 \mid r - l + 1\)。

可得:

\[f(i, j) = \sum_{k \in (l, r], 2 | k - i + 1} f(i + 1, k) \times f(k + 1, j) \times \binom{\frac {j - i + 1} {2}}{\frac {j - k + 1} {2}}
\]

其中 \(k\) 同学和 \(i\) 同学关系友好,且对于任意 \(i\),若 \(0 \leq i \leq n\),有 \(f(i, i + 1) = 1\)。

其中组合数可以理解为我们共有 \(\frac {j - i + 1} {2}\) 个盒子(盒子间被认为是不同的),且我们有 \(\frac {k - i - 1} {2}\) 个 \(a\) 球,\(1\) 个 \(b\) 球,和 \(\frac {j - k} {2}\) 个 \(c\) 球(同种类的球被认为是相同的,这是因为在上面的转移柿子中我们已经考虑了球种类内部的情况),且 \(b\) 球放入的盒子编号必须大于任意一个 \(a\) 球放入的盒子编号。

感性理解一下其实就是我们在所有的盒子中选 \(\frac {j - k} {2}\) 个出来放 \(c\) 球。

时间复杂度 \(O(n^3)\)。

  1. #include <cstdio>
  2. typedef long long LL;
  3. int Max(int x, int y) { return x > y ? x : y; }
  4. int Min(int x, int y) { return x < y ? x : y; }
  5. int Abs(int x) { return x < 0 ? -x : x; }
  6. int read() {
  7. int x = 0, k = 1;
  8. char s = getchar();
  9. while (s < '0' || s > '9') {
  10. if (s == '-')
  11. k = -1;
  12. s = getchar();
  13. }
  14. while ('0' <= s && s <= '9') {
  15. x = (x << 3) + (x << 1) + (s - '0');
  16. s = getchar();
  17. }
  18. return x * k;
  19. }
  20. void write(LL x) {
  21. if (x < 0) {
  22. x = -x;
  23. putchar('-');
  24. }
  25. if (x > 9)
  26. write(x / 10);
  27. putchar(x % 10 + '0');
  28. }
  29. void print(LL x, char s) {
  30. write(x);
  31. putchar(s);
  32. }
  33. const int MAXN = 4e2 + 5;
  34. const int mod = 998244353;
  35. bool w[MAXN][MAXN];
  36. LL q[MAXN], sq[MAXN], dp[MAXN][MAXN];
  37. LL A (int x, int y) { return q[x] * sq[x - y] % mod;}
  38. LL C (int x, int y) { return A(x, y) * sq[y] % mod;}
  39. LL Quick_Pow(LL a, LL b) {
  40. LL res = 1;
  41. while(b) {
  42. if(b & 1)
  43. res = res * a % mod;
  44. a = a * a % mod;
  45. b >>= 1;
  46. }
  47. return res % mod;
  48. }
  49. int main() {
  50. int n = read(), m = read();
  51. q[0] = 1, sq[0] = 1;
  52. for(int i = 1; i <= (n << 1); i++) {
  53. q[i] = q[i - 1] * i % mod;
  54. sq[i] = Quick_Pow(q[i], mod - 2);
  55. }
  56. for(int i = 1, a, b; i <= m; i++) {
  57. a = read(), b = read();
  58. w[a][b] = w[b][a] = true;
  59. }
  60. for(int i = 1; i <= (n << 1) + 1; i++)
  61. dp[i][i - 1] = 1;
  62. for(int len = 2; len <= (n << 1); len += 2)
  63. for(int l = 1; l + len - 1 <= (n << 1); l++) {
  64. int r = l + len - 1;
  65. for(int k = l + 1; k <= r; k += 2)
  66. if(w[l][k])
  67. dp[l][r] = (dp[l][r] + dp[l + 1][k - 1] * dp[k + 1][r] % mod * C(len / 2, (r - k + 1) / 2) % mod) % mod;
  68. }
  69. print(dp[1][n << 1], '\n');
  70. return 0;
  71. }

G - Groups

还是一道 dp 呢。

我们定义 \(f(i, j)\) 表示分完前 \(i\) 个数且当前分了 \(j\) 个组。

考虑当前数的两种决策。

第一种,新开一个组,即方案数为 \(f(i - 1, j - 1)\)。

第二种,不开新的组而是丢进已存在的组,不难发现当前数可以丢入的组共有 \(j - t(i, i \bmod m)\) 个,其中 \(t(x, y) = \sum_{i = 1}^{x} [i \bmod m = y]\)。

故可得,\(f(i, j) = f(i - 1, j - 1) + f(i - 1, j) \times (j - t(i, i \bmod m))\)。

初始状态为 \(f(0, 0) = 1\)。其他的比如 \(t(x, y)\) 的转移啦、答案状态啦就很简单了嘛,时间复杂度 \(O(n^2)\)。

  1. #include <cstdio>
  2. typedef long long LL;
  3. LL Max(LL x, LL y) { return x > y ? x : y; }
  4. LL Min(LL x, LL y) { return x < y ? x : y; }
  5. LL Abs(LL x) { return x < 0 ? -x : x; }
  6. int read() {
  7. int k = 1, x = 0;
  8. char s = getchar();
  9. while (s < '0' || s > '9') {
  10. if (s == '-')
  11. k = -1;
  12. s = getchar();
  13. }
  14. while (s >= '0' && s <= '9') {
  15. x = (x << 3) + (x << 1) + s - '0';
  16. s = getchar();
  17. }
  18. return x * k;
  19. }
  20. LL read_LL() {
  21. int k = 1;
  22. LL x = 0;
  23. char s = getchar();
  24. while (s < '0' || s > '9') {
  25. if (s == '-')
  26. k = -1;
  27. s = getchar();
  28. }
  29. while (s >= '0' && s <= '9') {
  30. x = (x << 3) + (x << 1) + s - '0';
  31. s = getchar();
  32. }
  33. return x * k;
  34. }
  35. void write(LL x) {
  36. if (x < 0) {
  37. putchar('-');
  38. x = -x;
  39. }
  40. if (x > 9)
  41. write(x / 10);
  42. putchar(x % 10 + '0');
  43. }
  44. void print(LL x, char s) {
  45. write(x);
  46. putchar(s);
  47. }
  48. const int MAXN = 5e3 + 5;
  49. const int mod = 998244353;
  50. int t[MAXN];
  51. LL dp[MAXN][MAXN];
  52. int main() {
  53. int n = read(), m = read();
  54. dp[0][0] = 1;
  55. for(int i = 1; i <= n; i++) {
  56. for(int j = 1; j <= n; j++)
  57. dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j] * ((j - t[i % m] + mod) % mod) % mod) % mod;
  58. t[i % m]++;
  59. }
  60. for(int i = 1; i <= n; i++)
  61. print(dp[n][i], '\n');
  62. return 0;
  63. }

H - Snuketoon

不会了不会了不会了 /fad。

Solution -「ABC 217」题解的更多相关文章

  1. Solution Set -「ABC 217」

      大家好屑兔子又来啦! [A - Lexicographic Order]   说个笑话,\(\color{black}{\text{W}}\color{red}{\text{alkingDead} ...

  2. Solution -「ABC 219H」Candles

    \(\mathcal{Description}\)   Link.   有 \(n\) 支蜡烛,第 \(i\) 支的坐标为 \(x_i\),初始长度为 \(a_i\),每单位时间燃烧变短 \(1\) ...

  3. Solution -「ABC 215H」Cabbage Master

    \(\mathcal{Description}\)   Link.   有 \(n\) 种颜色的,第 \(i\) 种有 \(a_i\) 个,任意两球互不相同.还有 \(m\) 个盒子,每个盒子可以被放 ...

  4. Solution -「ABC 213G」Connectivity 2

    \(\mathcal{Description}\)   Link.   给定简单无向图 \(G=(V,E)\),点的编号从 \(1\) 到 \(|V|=n\).对于 \(k=2..n\),求 \(H= ...

  5. Solution -「ABC 213H」Stroll

    \(\mathcal{Description}\)   Link.   给定一个含 \(n\) 个结点 \(m\) 条边的简单无向图,每条边的边权是一个常数项为 \(0\) 的 \(T\) 次多项式, ...

  6. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  7. Solution -「ARC 110E」Shorten ABC

    \(\mathcal{Description}\)   Link.   给定长度为 \(n\),包含 A, B, C 三种字符的字符串 \(S\),定义一次操作为将其中相邻两个不相同的字符替换为字符集 ...

  8. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  9. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

随机推荐

  1. kNN-识别手写数字

    最后,我们要进行手写数字分类任务,但是现在我们是用kNN算法,可能会比较慢 首先,完整地看完2.3.1和2.3.2的内容,然后找到trainingDigits和testDigits文件夹,大致浏览下 ...

  2. .NET性能优化-使用ValueStringBuilder拼接字符串

    前言 这一次要和大家分享的一个Tips是在字符串拼接场景使用的,我们经常会遇到有很多短小的字符串需要拼接的场景,在这种场景下及其的不推荐使用String.Concat也就是使用+=运算符. 目前来说官 ...

  3. Volatile的学习

    首先先介绍三个性质 可见性 可见性代表主内存中变量更新,线程中可以及时获得最新的值. 下面例子证明了线程中可见性的问题 由于发现多次执行都要到主内存中取变量,所以会将变量缓存到线程的工作内存,这样当其 ...

  4. 论文解读(NGCF)《LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation》

    论文信息 论文标题:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation论文作者:Xiangn ...

  5. 一个 "开箱即用" 个人博客全栈系统项目!vue+node+express+mysql+sequlize+uniapp

    " MG'Blog " 一个 "开箱即用" 个人博客全栈系统项目! 探索本项目的源码 » 前台预览 · 管理端预览 v1.0.2 小程序预览 v1.0.2 介绍 ...

  6. Linux下添加MySql组件后报无权限问题解决

    Tomcat日志报错如下: Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using pas ...

  7. Go微服务框架go-kratos实战03:使用 gorm 实现增删改查操作

    一.简介 在上一篇文章 go-kratos实战02 中,详细介绍了用 kratos 编写项目代码的步骤.这篇就在上篇基础上,再结合 Go 数据库操作库 gorm 一步一步来实现一个简单的增删改查操作. ...

  8. 毕设(1)——机械臂DH建模

    目录 毕设(1)--机械臂DH建模 改进DH参数表 Matlab代码验证 毕设中用到了很多代码,其中一部分我通过看书和看论文学习并实现的代码,会通过Gitee仓库分享出来,这些代码仅用于学习使用,祝各 ...

  9. transforms.py

    from PIL import Image from torchvision import transforms #python的用法-->tensor数据类型 #通过transforms.To ...

  10. JS数组at函数(获取最后一个元素的方法)介绍

    本文介绍js中数组的at函数,属于比较简单的知识普及性文章,难度不大. 0x00 首先,我们可以思考如下一个问题,如果要获取一个数组的最后一个元素(这是很常用的操作),我们应该怎么做? 相信大部分人能 ...