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$,搞一下前缀和之类的,可以快速转移。