AtCoder Beginner Contest 253 A—E
本题解思路来自于 spoonjunxi
A
题目描述
给定三个数$a,b,c$,判断$b$是否在$[a,c]$之间,如果是输出Yes
,否则输出No
。
题目分析
直接判断即可。
$Code$
1 | int a, b, c; |
$ \ $
$ \ $
B
题目描述
给定一个矩形,求出矩形中两个o之间的距离。
题目分析
曼哈顿距离公式。
$Code$
1 | int n, m; |
$ \ $
$ \ $
C
题目描述
给定一个multiset——S,最开始置为空。
给定Q个询问
1 x
:向S中插入$x$。2 x c
:在S中删除$min(c, x的个数)$个$x$。- 输出S中最大值$-$最小值。
题目分析
对于此题,题目要求我们使用multiset,但为了方便,我们使用set,用数组来统计每个$x$出现的次数。
由于$0 \le x \le 10^9$,用数组开会浪费空间。
注意到询问次数$1 \le Q \le 2 \times 10^5$,最多$2 \times 10^5$,启发我们可以使用unordered_map来记录每个数出现的次数。
unordered_map<int, int> mp
;
$Code$
1 | int main() |
$ \ $
$ \ $
D
题目描述
求出$1$到$N$中不是$A$的倍数,或者不是$B$的倍数的总数和是多少。
题目分析
利用容斥原理。
如图,总数和就是大圈减去两个小圈在加上两个小圈的重合部分。
对于A的倍数的总和:
$q_1 = N / A$:$1$到$N$中$A$的倍数的数有多少个。
假设$N$ = 10,$A$ = 3。
$q_1$ = 3,说明有三个数是$A$的倍数,分别为$3、6、9$。
如何求它们的和呢?
我们发现它们呈现等差数列的现象,公差为$a$,有$q_1$个数字。
于是$suma = \frac{q_1 (q_1 + 1)}{2} \times A$
同理我们可以求出:
B的倍数的总和:
$q_2 = N / B$
$sumb = \frac{q_2(q_2 + 1)}{2} \times B$
A,B最小公倍数的倍数的总和(既是A的倍数,也是B的倍数的总和):
$q_3 = N / lcm(A,B)$
$sumc = \frac{q_3(q_3 + 1)}{2} \times lcm(A,B)$
所有数的总和:
$\frac{N (N + 1)}{2}$
于是答案就是$\frac{N (N + 1)}{2} - suma - sumb + sumc$
注意开long long!!!
$Code$
1 | typedef long long LL; |
$ \ $
$ \ $
E
题目描述
有多少个长度为$N$的 $A$数组。
满足
- 每一位小于$M$
- 相邻两位的的绝对值之差小于$K$
答案MOD$998244353$
题目分析
由于每一位与前面一位有关系,启发我们可以使用动态规划。
优化
在状态计算中,我们可以通过前缀和的思想进行优化。
求$\sum_{u = 1}^{j - k} f[i][u]$
可以开个前缀和数组$s$,用来记录上一层所有情况的前缀和。
$$\sum_{u = 1}^{j - k} f[i][u] = s[j - k]$$
$$\sum_{u = j + k}^{n} f[i][u] = s[n] - s[j + k - 1]$$
注意
$k$的取值可能为0,此时注意特判一下即可。
$Code$
1 | typedef long long LL; |
为什么要加MOD在模MOD呢???
感谢 Gzm1317 巨巨的解答。
因为在处理前缀和的时候用了s[j] = (s[j - 1] + f[i - 1][j]) % MOD
。
可能会导致$s[m] < s[b - 1]$的情况出现,于是需要加上一个MOD,防止出现负数的情况。