COMPFEST 15 - Preliminary Online Mirror 补题
A Ambitious Kid
题面翻译
给定一个 $N(1 \leq N \leq 10^5)$,给定一个数组 $A_i$,每次可以让一个数 $ +1/-1 $,求至少多少次操作能使 $A_1 \times A_2 \times A_3 \times \cdots \times A_N=0$。
Sol
签到题。
答案是所有数绝对值最小的那个。
B Completely Searching for Inversions
题面翻译
给定一个有 $ N $ 个结点的有向无环图。结点 $ i $ 的出度为 $ S_i $。结点 $ i $ 的第 $ j $ 条出边指向 $ L_{i, j} $,边权为 $ W_{i, j} \text{ } (0 \le W_{i, j} \le 1) $。给出的图保证从结点 $ 1 $ 出发可以到达所有结点。
给定初始为空的数组 $ Z $。
定义函数 $ \texttt{dfs} $ 如下:
// 以结点 i 为起点进行 dfs
void dfs(int i) {
    // 遍历 i 的每条出边
    for(int j = 1; j <= S[i]; j++) {
        Z.push_back(W[i][j]); // 将当前边的边权加入数组 Z 的末尾
        dfs(L[i][j]); // 从下一个结点继续 dfs
    }
}请注意,以上函数并没有记录经过的结点,所以有些结点可能被经过不止一次。
在主函数中,程序调用了一次 $ \texttt{dfs(1)} $,得到了一个只包含 $ 0 $ 和 $ 1 $ 的数组 $ Z $。请你求出数组 $ Z $ 的逆序对数。
由于答案可能很大,你只需要输出答案对 $ 998 \text{ } 244 \text{ } 353 $ 取模的值。
Sol
考虑暴力时重复的子问题:dfs 过程中一个点会被经过多次,于是考虑优化掉这部分。
发现从一个节点往下 dfs,对 $ Z $ 序列的新增区间相同,新产生的贡献 = 新增区间逆序对个数 + 原 $ Z $ 序列 $ 1 $ 的个数 $ \times $ 新增区间 $ 0 $ 的个数。
于是对于 $ DAG $ 上的每一个点,用 $ O(n) \ dfs $ 维护出 从该点遍历对 $ Z $ 序列新增区间中 $ 0 $ 的个数/$ 1 $ 的个数/逆序对个数,然后按儿子合并即可。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号