CF1556C&D&F题解
C
\(n\le 1000\),考虑用 \(n^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\),需要满足两个条件。
- 全集为 \(i\) 时 \(i\) 内部全是 winner;
- \(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 链接吧。