Codeforces Round #902 (Div.1)

发布时间 2023-10-08 20:17:51作者: 云浅知处

A

注意到 \(a_i\ge 1\),因此我们先花 \(p\) 的代价买下 \(b\) 最小的,然后一定可以一直用当前可能的最小代价买下后续的人。不难发现这一定是最优的方案。

只需要将序列排序或者用 std::multiset 来维护。单组数据时间复杂度 \(O(n\log n)\)

https://codeforces.com/contest/1876/submission/227124154

B

考虑对 \(v=0,1,\cdots,10^5\) 算出 \(\max >v\) 的方案数,全部求和就是所有方案的 \(\max\) 之和。

考虑怎么算 \(\max >v\) 的方案数,用 \(2^n\) 减去 \(\max \le v\) 的方案数即可,而 \(\max \le v\) 相当于选出的数中只能有 \(\le v\) 的数。考虑每个 \(x=1,2,\cdots,n\),如果 \(x\) 的所有倍数位置都 \(\le v\) 那就可以选中 \(x\),否则一定不能选中 \(x\)。那么方案数就是 \(2\) 的可以选中的位置的个数次幂。

提前预处理出来 \(1\sim n\) 中所有数的约数集合,然后每次加入 \(=v\) 的数,枚举这些数的位置的约数看是否符合条件即可。复杂度 \(O(n\log n)\)

https://codeforces.com/contest/1876/submission/227128795

C

考虑对每个 \(i\) 连有向边 \(i\to a_i\),那么将得到一个内向基环森林。下面我们用 \(i\) 是白色表示 \(i\) 未被圈住,黑色表示 \(i\) 被圈住。那么可以发现,一个染色方案合法当且仅当:

  • 对每个白色的位置 \(i\)\(a_i\) 需要是黑色的。
  • 对每个黑色的位置 \(i\),至少存在一个 \(j\) 使得 \(a_j=i\),且 \(j\) 是白色的。

考虑拓扑排序,先把所有入度为 \(0\) 的点确定为白色,接下来根据上面的两个条件有两种转移:

  • \(x\) 确定为白色,则 \(a_x\) 确定为黑色。
  • \(x\) 的所有前驱都已经确定为黑色,则 \(x\) 可以被确定为白色。

进行拓扑排序并删掉所有已经确定颜色的点后,图中只会剩下若干个环。如果此时剩下了奇环则无解,否则将每个偶环交替黑白染色即可。时间复杂度 \(O(n)\)

代码用了并查集来帮助找环,其时间复杂度为 \(O(n\log n)\)

https://codeforces.com/contest/1876/submission/227148089

D

题目相当于对每种颜色确定用 RBRB... 还是 BRBR... 的方案进行染色。

注意到红蓝两色是完全对称的,因此红色字典序严格更小的方案数等于蓝色字典序严格更小的方案数。设出现至少一次的颜色数为 \(c\),则总的方案数为 \(2^c\)。如果红蓝相同的方案数是 \(w\),那么答案就是 \(\frac{1}{2}(2^c-w)\)。现在只需要算出 \(w\)

首先,如果有一种颜色的出现次数为奇数,则必有 \(w=0\);否则,考虑每种颜色,设其出现位置依次为 \(p_1,p_2,\cdots,p_{2k}\),我们把它看作 \(k\) 个区间 \([p_{2i-1},p_{2i}]\),其中 \(1\le i\le k\)

考虑两种颜色 \(i,j\),如果存在 \(i\) 的一个区间和 \(j\) 的一个区间相交但互不包含,那么我们在 \(i,j\) 之间连边;如果 \(i\) 的某个区间包含 \(j\) 的某个区间或者 \(j\) 包含 \(i\),那么必有 \(w=0\)。连边之后,设连通块个数为 \(x\),那么有 \(w=2^x\)

直接枚举两种颜色是不行的,考虑把所有区间放在一起按左端点排序,只考虑相邻的两个区间之间的连边即可。包含的情况也容易处理。不难做到 \(O(n\log n)\) 的复杂度。

https://codeforces.com/contest/1876/submission/227180729