zoukankan      html  css  js  c++  java
  • 省选模拟55 题解

    A. 调兵遣将

    对于一个确定的右端点,只有 $log$ 种 $gcd$ 不同的左端点。

    可以把这个东西写成 $(a,b,R)$ 的形式。

    在集合中不便于计算,可以考虑转化为总方案数减不在集合中的方案数。

    可以考虑设 $f_x$ 表示最后一个区间的右端点 $leq x$ 的方案数,然后对上面那个三元组按照 $R$ 排序即可转移。

    转移的操作是区间求和和区间修改,用一个线段树即可维护。

    为了统计答案,设 $g_x$ 表示类似的,但是是从右向左进行的 dp。

    总方案数即 $f_n$ ,点 $i$ 不在集合中的方案即 $f_{i-1}g_{i+1}$。

    然后发现很多连续的 $f_{i-1}g_{i+1}$ 取值是相同的,所以对于每个相同的区间进行一下区间修改即可。

    B. 一掷千金

    翻硬币游戏的一个结论是:

    局面的 $SG$ 函数值为每个可以翻动的点单独存在的局面 $SG$ 函数值的异或和。

    然后可以发现一个点 $x$ 的 $SG$ 函数值为 $lowbit(dep_x)$。

    所以问题就是维护矩阵的并的 $lowbit(max(i,j))$ 的异或和。

    那肯定要搞一个扫描线。因为 $n$ 很小,所以直接枚举横坐标即可。

    然后对于纵坐标用线段树维护,问题就剩下了如何维护区间的 $lowbit$ 异或和。

    考虑把这个线段树的大小恒定为 $2^{30}$,于是每次询问的区间形式均为 $[a*2^b,(a+1)*2^b)$。

    然后考虑区间内 $x$ 形成的 $lowbit(x)$ ,如果 $lowbit(x) < 2^{b-1}$,那么不管第一个 $1$ 位,对于剩下的高位取反,可以取得恰好相同的 $lowbit$。

    这样两两对应可以消完。没消掉的只剩下 $lowbit(a*2^b)$ 和 $lowbit(a*2^b+2^{b-1})$,异或起来就是答案了。

    C. 树拓扑序

    考虑把问题转化为点对贡献。也就是说枚举 $(a,b),a<b$ 钦定 $a$ 在 $b$ 后面出现,然后计算一下满足的拓扑序个数。

    首先考虑如何计算拓扑序总数。因为树的形式比较简单,每次考虑一个新增的子树插入原有的序列即可。

    然后考虑怎么把现在的限制加进去,发现只要维护一下 $a,b$ 在当前子树中分别的排名就好了。

    具体来说,在 $lca(a,b)$ 处合并两个子树的信息。在 $a -> lca(a,b)$ 处维护 $a$ 每个排名的拓扑序个数。在 $b -> lca(a,b)$ 处维护 $b$ 每个排名的拓扑序个数。在  $lca(a,b) -> 1$ 处直接合并无关信息的贡献。

    这样做就是 $O(n^4)$ 的。

    然后发现每次只做一个 $b$ 太亏了,我们现在只关注 $b>a$ 这条信息,不关注 $b$ 具体是谁了。

    所以可以只枚举一个 $a$ ,然后对于所有的 $b>a$ 统一做一个各种子树归并 dp。

    这样复杂度就是 $O(n^3)$ 的了,但是常数太大不是正解,所以在 hzoj noilinux 神机下跑不过去。

    正解其实差不太多,思想大概是可以直接维护每个点每个排名合法的拓扑序个数。

    然后对于每个 $lca$,搞一下前缀和之类的,可以快速转移。

  • 相关阅读:
    python库安装
    Reversing Linked List(根据输入序列对其做部分或全部反转)
    简单的一元二项(使用的是指针形式,方便调试)
    最大子序列问题
    centos6安装mysql5.5.53
    android中常用的drawable
    android四大组件之ContentProvider
    android使用shape来绘制控件
    android布局理解
    android命令行管理avd以及sqlite3命令
  • 原文地址:https://www.cnblogs.com/skyh/p/12584508.html
Copyright © 2011-2022 走看看