扩大
缩小

AtCoder Beginner Contest(ABC) 247 A~G 题解

点击各题标题可以跳转到原题。

A - Move Right(Difficulty: 14)

Statement:将长度为 $4$ 的 01 串整体右移一位。

Solution这个有什么好说的吗

Codehttps://atcoder.jp/contests/abc247/submissions/30847456

B - Unique Nicknames(Difficulty: 202)

Statement

  • 给 $n$ 个人的姓、名,问是否每个人都有别人所没有的姓或名。
  • $n \le 100$,记最大串长为 $s$,有 $s \le 10$。

Solution

  • 算法一:对于每一个人的姓名,对其他人逐个枚举判断,$\mathcal{O}(n^2s)$。
  • 算法二:用 std::map 存每个人字符串,枚举的时候看看姓、名是否只有自己出现。时间复杂度 $\mathcal{n \log n}$,有大常数。
  • 算法三:用 Trie 存下所有的姓名串,记录末尾节点的访问次数。时间复杂度 $\mathcal{O}(ns)$,空间复杂度$\mathcal{O}(26ns)$。

Codehttps://atcoder.jp/contests/abc247/submissions/30852679

C - 1 2 1 3 1 2 1(Difficulty: 149)

Statement

  • 有一个初始序列 $[1]$。
  • 现在进行 $n$ 次操作,第 $i$ 次操作将自己复制一遍,拼到末尾,正中间再插入一个数 $i$。
  • 问 $n$ 次操作后的数列。$n \le 16$。

Solution

  • 没什么好说的,直接模拟即可,数组不要开小了。

Codehttps://atcoder.jp/contests/abc247/submissions/30854775

D - Choose Me(Difficulty: 468)

Statement

  • 维护 $Q$ 次操作,操作分两种。
  • 1. 队尾插入 $c$ 个权值均为 $x$ 的球。
  • 2. 从队头取出 $c$ 个球,并输出这 $c$ 个球的权值和。
  • $Q \le 200000, \ c,x \le 10^9$。

Solution

  • 像维护队列那样,找一个指针,记录当前正在取第几个操作放进去的球,以及这一批球剩几个。
  • 时间复杂度 $\mathcal{O}(Q)$。

Codehttps://atcoder.jp/contests/abc247/submissions/30859907

E - Through Path(Difficulty: 1256)

Statement

  • 有一个长度为 $n$ 的序列 $a_1,a_2,...,a_n$。
  • 给出两个数 $x,y$,问区间最大值等于 $x$,最小值等于 $y$。
  • $1 \le n,a_i,x,y \le 200000$。

Solution

  • 二分/双指针 + 线段树/ST表都是经典问题,可以快速解决,但是时间复杂度至少带个 $\log$,码量也大。代码点这里
  • 这里简单讲下 $\mathcal{O}(n)$ 且很好写的做法:
    • 从左到右枚举,对每个位置 $i$ 记录在自己以左,且分别等于 $x,y$ 的距离自己最近的位置 $u,v$。
    • 再记录自己以左且最近的大于 $x$ 或小于 $y$ 的位置 $w$。
    • 若 $\min(u,v)-w>0$,那么答案就累加 $\min(u,v)-w$。最后输出累加的和。

线性复杂度做法代码https://atcoder.jp/contests/abc247/submissions/30895819

F - Cards(Diffyculty: 1697)

Statement

  • 有两个 $1 \sim n$ 的排列 $p_1,p_2,..,p_n$,$q_1,q_2,...,q_n$。
  • 你可以选若干个下标 $a_1,a_2,...,a_m$,使得 $p_{a_1},q_{a_1},p_{a_2},q_{q_2},...,p_{a_m},q_{a_m}$ 构成的集合包含完整 $1 \sim n$ 的排列。
  • 求方案数对 $998244353$ 取模的值。
  • $n \le 200000$。

Solution

  • 我们按照 $p_i$ 大小把 $q_i$ 排序,这样 $p_i$ 变为 $1,2,...,n$,可以当下标用。设位置 $i$ 现在的值为 $c_i$
  • 若 $c_i=i$,代表我们选了下标 $i$ 时只得到了 $i$。
  • 若 $c_i \neq i$,相当于我们选下标 $i$ 时得到了 $i,c_i$ 两个值。
  • 由于 $p,q$ 数组是两个排列,因此每个元素恰好会出现两次。
  • 由于 $i$ 位置的值是 $c_i$,所以下标是 $c_i$ 的值肯定又指向了另一个数。不难发现,这样一直指下去一定会形成一个环。
  • 那么这 $n$ 个值就被分割成了若干个大小不一的环。由于环与环之间是独立的,我们只要计算每个环的方案数,最后乘起来就可以。
  • 问题可以转换成:$1,2,...,m$ 绕成一个环,有多少个选数方案使得每相邻两个位置至少被选了一个数
  • $m=1,2$ 时答案很显然,为 $1,3$。
  • $m>2$ 时,假设我们从原来的环 $1,2,...,m-1$ 插入一个 $m$。
    • 令环大小为 $m$ 的答案为 $f(m)$,那么有关系式 $f(m)=f(m-1)+f(m-2)$。
    • 这个式子可以理解为 $1,2,...,m-1$ 的环插入元素 $m$,$m$ 选/不选得到的方案数和。读者可以自证一下。

Codehttps://atcoder.jp/contests/abc247/submissions/30876626

G - Dream Team(Difficulty: 2159)

Statement

  • 有 $N$ 个人,每个人有两个属性 $a_i,b_i$,以及他的价值 $c_i$。
  • 现在要从这 $N$ 个人中选择 $k$ 个人,要求这 $k$ 个人两两的 $a_i$ 不相同,两两的 $b_i$ 也不相同。
  • 请问 $k$ 的最大可能值 $k_0$ 是多少?对于 $k=1,2,...,k_0$,求出恰好选择 $k$ 人所能得到的最大价值和。
  • $N \le 30000$,$a_i,b_i \le 150$。

Solution

  • 很容易想到网络流。既然要每个 $k$ 都算答案,我们如果每次在初始的图上限流,跑 $k$ 次 MCMF 时间复杂度就炸了。
  • 这时我们应该联想到 EK 算法是单线程求网络流的,可以理解为如果流入边限制为 $1$,那么 EK 算法每增广一次,最大流最多增加 $1$。
  • 然后就可以用这个性质,只需要跑一次 MCMF 即可。
  • 虽然时间复杂度上界是 $\mathcal{O}(fnm)=150^4$ 的($f$ 是最大流,$n$ 是点数,$m=n^2$),但是卡不满,所以跑得非常快。

代码https://atcoder.jp/contests/abc247/submissions/30893129

posted @ 2022-04-15 22:03  HoshizoraZ  阅读(353)  评论(0编辑  收藏  举报