abc368 题解
切了 ABCDF,G 赛后 1min 切了(恼
比赛链接:https://atcoder.jp/contests/abc368
A - Cut
题意:
给定一个长度为 \(n\) 的序列,先输出后 \(k\) 个数,在输出前 \(n-k\) 个数。
思路:
按题意模拟即可。
代码:
https://atcoder.jp/contests/abc368/submissions/57030066
B - Decrease 2 max elements
题意:
给定一个长度为 \(n\) 的序列,定义一次操作为将序列中的最大值和次大值减去一,请问几次操作过后,序列中有至多 \(1\) 个正整数。(\(2\le n\le 100,1\le a_i\le 100\))
思路:
按题意模拟即可。
代码:
https://atcoder.jp/contests/abc368/submissions/57041828
C - Triple Attack
题意:
给定一个长度为 \(n\) 的序列,\(T\) 初始为 \(0\),定义一次操作为:
- 将 \(T\gets T+1\)。
- 将序列中的第一个正整数减去 \(c\)。
- 若 \(T\equiv 0\pmod 3\),则 \(c=3\)。
- 否则 \(c=1\)。
请问几次操作过后,序列中没有正整数。
思路:
可以发现每 \(3\) 次操作一定会减去 \(5\),所以考虑先将第一个数花 \(3\) 次操作减 \(5\) 的整体操作,之后暴力做小部分操作即可。
代码:
https://atcoder.jp/contests/abc368/submissions/57052296
D - Minimum Steiner Tree
题意:
给定一颗 \(n\) 个节点的树,再给定树上的 \(k\) 个点 \(x_1,x_2,\cdots x_k\),求包含这 \(k\) 个点的最小生成树大小。(\(1\le k\le n\le 2\times 10^5\))
思路:
考虑以 \(x_1\) 为根,容易发现若节点 \(u\) 一定要被包含,那么其父亲也一定要被包含,考虑设 \(vis_i\) 表示节点 \(i\) 是否被包含,然后 dfs 遍历每一个节点并回溯转移即可。
代码:
https://atcoder.jp/contests/abc368/submissions/57055501
E - Train Delay
不会……
F - Dividing Game
题意:
Anna 和 Bruno 在玩一个游戏。给定一个长度为 \(n\) 的序列 \(a_1,a_2,\cdots,a_n\),每次操作 Anna 或 Bruno 可以选择序列中的一个数,将其变成其因数(但不能不变),请问若 Anna 先手,双方都已最佳方式玩游戏,谁会取胜。(\(1\le n\le 10^5,2\le a_i\le 10^5\))
思路:
先将每个 \(a_i\) 分解质因数,发现操作就相当于在 \(a_i\) 的质因数中去掉几个(但不能不去),质因数全去掉就不能继续对 \(a_i\) 操作。设 \(c_i\) 为 \(a_i\) 的质因数个数(可以用筛法求出),那么题目就转化成了 Nim 游戏。
代码:
https://atcoder.jp/contests/abc368/submissions/57065741
G - Add and Multiply Queries
题意:
你有两个长度为 \(n\) 的序列 \(a,b\),你要处理如下 \(q\) 次操作(\(1\le n\le 10^5,1\le q\le 10^5\)):
- 将 \(a_x\gets y\)。
- 将 \(b_x\gets y\)。
- 有一个变量 \(T\) 初始值为 \(0\),依次遍历 \(i=l,l+1,\cdots,r\) 每次将 \(v\gets v+a_i\) 或 \(v\gets v\times b_i\)。输出 \(T\) 最后可能的最大值。
保证第 3 种操作的答案最大为 \(10^{18}\)。
思路:
最后的条件非常重要,如果 \(b_i\le 1\) 那么肯定选择将 \(v\gets v+a_i\),否则将 \(v\gets \max(v+a_i,v\times b_i)\)。后者情况的 \(b_i\ge 2\),由于 \(2^{64}>10^{18}\),我们可以知道最多只有 \(64\) 个 \(b_i\) 大于 \(1\),所以我们可以用 set
或 vector
维护这些 \(b_i\) 的下标 \(i\),然后在每次查询的时候遍历 set
或 vector
中在 \(l\) 到 \(r\) 以内的数,对于 \(b_i\le 1\) 我们需要区间查询 \(a\) 数组中某一段区间的和,对于 \(b_i\gt 1\) 我们可以暴力处理。由于需要单点修改某个数的值,第 1 种操作可以用树状数组维护,第 2 种操作可以用用 set
或 vector
暴力处理。