agc023 题解
A \(\color{gray}\bigstar\)
查询前缀和相等即可。
B \(\color{green}\bigstar\)
先把图扩展成 \(2n\times 2n\),然后每次问一条对角线即可。
C \(\color{blue}\bigstar\)
降智题。
开始在考虑恰好怎么做,大概就是枚举一个合法情况再考虑最后一个操作什么,可以得到一个 \(O(n^2)\) 的东西,但是无法优化。
考虑拆个贡献,算 \(i\) 步还没有完成的方案数,这个可以简单插板法即可。
D \(\color{gold}\bigstar\)
很久之前做的题了。
倒过来考虑,对于最外面的两个东西,显然那边人多就先到那边,而人少那边在前面的投票中也会先投给人多那边,这样让自己更快。
因此把左右端点不断往中间缩,模拟即可。
E \(\color{blue}\bigstar\)
典题。
令 \(b\) 表示 \(a\) 排序后的结果,\(c_i\) 表示 \(i\) 的排名。
合法排列数为 \(\prod (b_i-i+1)\)。
考虑 \(i,j(i<j)\) 的贡献。
如果 \(a_i<a_j\),那么令 \(a_j=a_i\) 后答案不变,此时贡献为方案数为前缀不变,后缀不变,中间全部减一,再乘上这两个数的方案数。
可以前缀积一下,然后发现得到一个 \(s_is_j\) 这样的式子,离线一下,从小到大加入 \(a_i\),然后查询前缀即可。
如果 \(a_i>a_j\),那么就倒过来,用总对数减去顺序对个数,就得到和上面一样的问题。
前缀和可以用树状数组维护。
有一个问题是中间减一后可能前缀积变成了 \(0\),此时注意到相当于询问一个区间的值,因此如果遇到一个 \(s_i=1\) 的东西直接清空树状数组即可。
F \(\color{gold}\bigstar\)
题解区证明比较神秘啊。
\(01\) 序列逆序对可以转化成,\(1\) 就向下走一格,\(0\) 向右走一格,然后形成折线左下角的面积就是逆序对数。
考虑合并两个 \(01\) 序列,可以发现最后一整段的属于同一个序列的折线连起来,形成的是一个下凸壳,进而可以发现直接每次找 \(\frac{s_0}{s_1}\) 最大的即可。
但是转移到了树上,可以发现两个序列合并时,所有方案的壳一定严格包含最优壳,所以这样保证了子树最优,全局最优,因此只需要维护从根出发,每次选一个 \(\frac{s_0}{s_1}\) 最大的连通块。
这个东西好像很难维护,看题解。
用并查集和堆维护,每次选一个 \(\frac{s_0}{s_1}\) 最大的连通块,和父亲的连通块合并即可。