对于一条重链,其节点dfn序的顺序是从上往下依次增大,那么正常写法的线段树(从左往右乘),矩阵的乘法顺序是按节点从上往下,最终得到的答案矩阵两个系数也是反过来的。然而实际dp过程中理应是矩阵从下往上依次相乘,这样才能得到正常的系数顺序。
那么,如果我们将代码中的
tr[u].sum=tr[u<<1].sum*tr[u<<1|1].sum;
改为
tr[u].sum=tr[u<<1|1].sum*tr[u<<1].sum;
我们能得到正常的结果吗?
答案是不行。
以下是我的见解:
记链上的节点转移矩阵从上往下依次为 A1、A2、A3…An−1、An,答案矩阵记为 ans,由于我们的推出的矩阵满足 ans=Ai∗ans,所以整个式子是 A1×(A2×(A3…(An−1×An)…),由于矩阵满足结合律,可以将括号去掉,那么按序相乘是正确的。
但是如果我们将代码改成后者,最终得到的式子是An×An−1…A2×A1,由于矩阵没有交换律,所以这样是错误的。
希望可以帮助到大家。