CF1556C&D&F题解

C

\(n\le 1000\),考虑用 \(n^2\) 算法。

枚举最左边和最右边的括号分别在哪个位置,那么中间的部分已经被确定了。

我们只需要知道端点取在哪里。

如上图左右端点有三种取法。

我们再考虑合法的括号序列的条件:

  1. 左右括号数量相等;
  2. 任何位置左边的左括号数量不小于右括号数量。

我们固定左端点,每次向右扩展,同时算出最左边端点至少选多少个才能满足条件 \(2\)

再维护一个左右括号的数量差。

这样就能算出能选多少个了。

代码见 link

D

a+b=((a|b)^(a&b))+2(a&b)

这样可以在知道 \(a\) 的情况下两次求出 \(b\)

同时可以通过 \(6\) 次求出 \(a+b,b+c,a+c\) 来获得 \(a,b,c\)

这样就是 \(2n\) 次操作。

F

显然是状压。

\(dp_i\) 表示假设全集为 \(i\),集合 \(i\) 内部全是 winner 的概率。

这个东西不好求,反向求假设全集为 \(i\),集合 \(i\) 内部全是 winner 的概率。

枚举 \(i\) 的子集 \(j\),表示 \(i\) 中 winner 集合为 \(j\)

那么贡献为 \(dp_j \times \text{(j 中所有队伍都打败了 j 以外 i 以内的队伍的概率)}\)

\(dp_i\) 中减掉这份贡献就行了。

接下来求出答案。

若 winner 集合为 \(i\),需要满足两个条件。

  1. 全集为 \(i\)\(i\) 内部全是 winner;
  2. \(i\) 的队伍吊打 \(i\) 以外的所有队伍。

暴力算这部分就行。

贡献是 \(size_i\times dp_i\times (\prod\limits_{x\in i}\prod\limits_{y\not\in i}\dfrac{a_x}{a_x+a_y})\)

代码太丑了,挂个 CF 链接吧。

posted @ 2021-08-31 08:57  cmll02  阅读(114)  评论(0)    收藏  举报