• Codeforces Global Round 18 A~F 题解


    比赛链接

    A

    容易发现总和不会变。

    那么如果总和是 \(n\) 的倍数就输出 \(0\),否则输出 \(1\)

    Code:https://paste.ubuntu.com/p/gZZnwtB3VS/

    B

    对于二进制每一位都记录一下前缀和,删除最少 \(\Lrarr\) 保留最多,对每一位取 \(\max\) 即可。

    Code:https://paste.ubuntu.com/p/44pb5QMm5N/

    C

    模拟几次操作后可以看出,连续两次操作其实就相当于交换原序列的两个数。

    那么如果操作偶数次,相当于交换一些 \(01\) 对,最小次数就是 \(a\)\(b\) 不同的位数,当然要保证 \((a_i=0,b_i=1)\)\((a_i=1,b_i=0)\) 的数量一样。

    如果操作奇数次,最后一次肯定剩下一个位置 \((a_i=1,b_i=1)\),其他位置全都不同。那么要保证原串中 \((a_i=1,b_i=1)\) 的数量要恰好等于 \((a_i=0,b_i=0)\) 的数量 \(+1\)

    Code:https://paste.ubuntu.com/p/YtnHS9rj2T/

    D

    一个小结论:\(\text{popcount}(x\oplus y)\mod 2=(\text{popcount}(x)\mod2)\oplus(\text{popcount}(y)\mod 2)\)

    证明考虑异或的本质是不进位加法,每次只会消掉偶数个 \(1\)

    所以每条边的权值都可以换成 \(0/1\)

    比较显然的结论:\(u_i\)\(v_i\) 路径上的权值异或和 \(=\) 根到 \(u_i\) 路径上的权值异或和 \(\oplus\) 根到 \(v_i\) 路径上的权值异或和。

    \(a_i\) 表示根到 \(i\) 路径上的权值异或和。显然 \(a_i\in\{0,1\}\)

    那么给出若干个限制其实就是说 \(a_{u_i}\oplus a_{v_i}=0/1\),每条已给定边权的边同样给出了一个限制。

    不难想到 可以用扩展域并查集做。每个点开两个节点 \(b_{i,0/1}\),如果有一个限制就将对应的节点所在集合合并。无解的情况就是有限制不能满足或者 \(b_{i,0}\)\(b_{i,1}\) 在同一个集合里。

    实现的时候可以强制将小的点向大的点合并,这样求出 \(a_i\) 的时候就可以知道 \(i\)\(root\) 是否选的是同一个数。肯定有一堆其他写法,毕竟这是扩展域并查集板子……

    Code:https://paste.ubuntu.com/p/D5V2KXCFGC/

    E

    发现三个变量不好整,于是把 \(w\) 换成 \(n-r-b\),原式变为 \((n-r-b)(r-b)=r(n-r)-b(n-b)\)

    那么第二个人肯定会最大化 \(b(n-b)\),这是一个关于 \(b\) 的二次函数,在 \(b=\frac{n}{2}\) 的时候最大。

    不难发现如果第二个人能选 \(x\) 个点,那么肯定能选 \(x-1\) 个点。把选择的子树的根去掉,把它所有儿子的子树都选掉即可。因此第二个人会选的节点一定是 \(\min(\frac{n}{2},y)\),其中 \(y\) 是第二个人能选择的染蓝的最大节点数。所以第一个人的目的肯定就是最小化第二个人选的染蓝的节点数。如果有所保留,那么第二个人选掉就肯定不优。

    考虑第一个人操作的实质,其实就是把一个点到根的路径上的所有点设成第二个人不能选。

    不难发现选叶子节点一定比选它的祖先更优。那么问题就变成选一些叶子节点,使它们到根的路径的并的大小最大。这个可以长链剖分后贪心做。

    Code:https://paste.ubuntu.com/p/WnnhM2NjZY/

    F

    也是一道神仙题。

    看到两个相邻的 \(0/1\) 不好处理,于是考虑一个套路:将所有奇数位上的 \(0\to1\)\(1\to0\),这样每次操作也就是交换相邻的两个 \(01/10\)

    首先有解的充要条件就是 \(s\)\(t\) 在转化后 \(1\) 的数量相同。

    实际上,\(s\)\(t\) 的距离就是 \(\sum\limits_i\) 两个串中第 \(i\)\(1\) 的位置差。这样还是不好计数,考虑转化一下:设 \(x_i=\sum\limits_{j=1}^i[s_j=1]\)\(y_i=\sum\limits_{j=1}^i[t_j=1]\),那么 \(s\)\(t\) 的距离就是 \(\sum\limits_{i=1}^n|x_i-y_i|\)。意思就是说每一个 \(s\) 中的第 \(i\)\(1\)\(t\) 中第 \(i\)\(1\) 的贡献是二者的位置差。

    这种方法成功将每一位的贡献拆开,那么根据这个就可以 DP 了。设 \(pre_{i,j}\) 表示考虑到前 \(i\) 位,\(x_i-y_i=i\) 的方案数,\(suf_{i,j}\) 表示考虑后 \(i\) 位,后 \(i\) 位中 \(s\)\(1\) 的数量与 \(t\)\(1\) 的数量的差。

    转移的时候枚举这一位填 \(1/0\),最终答案就是 \(\sum\limits_{i=1}^n\sum\limits_{j=-n}^n pre_{i,j}\times suf_{i,-j}\times|j|\)

    Code:https://paste.ubuntu.com/p/WrbFFZyCR2/

  • 相关阅读:
    http数据返回值
    刷新 返回
    微信平台上遇到的bug
    iscroll修改
    iscroll
    a标签的herf和click事件
    ios9+xcode7 适配笔记
    xsd、wsdl生成C#类的命令行工具使用方法
    xcode更新,想想也是醉了
    关于#define预处理指令的一个问题
  • 原文地址:https://www.cnblogs.com/xsl19/p/cgr18_sol.html
Copyright © 2020-2023  润新知