算法 {区间翻转}
区间翻转
定义
A = [0,1,2,3,4,5]
, 翻转A[1-4]
得到A = [0,4,3,2,1,5]
;
算法
SplayTree维护动态翻转 (翻转与查询同步)
定义
对于序列A, 假设其对应SplayTree的子树为S
(即子树S的所有节点的中序遍历 就对应序列A);
则, 你对S的所有节点x
执行swap(x.lefSon, x.rigSon)
操作后, 此时的S树的中序遍历 就对应为A的翻转序列
;
子树:
d
b f
a c e g
其中序遍历是:[abcdefg]
(翻转所有节点的左右儿子)后的子树:
d
f b
g e c a
其中序遍历是:[gfedcba]
因此, 我们令懒标记Rev: 对节点x的左右儿子执行swap操作
, 那么对于翻转[l-r]
区间操作, &S树: 区间[l-r]对应的子树
, 则等价于: 对&S的所有节点
施加懒标记操作, 即对&S树根
添加懒标记;
代码
bool Lazy_::Reverse; // 如果为`1` 表示对节点的左右儿子执行swap操作;
void __Modify_byLazy( Lazy_ const& _newLazy){
if( _newLazy.Reverse != false){ // 這裡要與`Lazy_::IsEmpty`裡面的判斷一致
//>> 更新懶標記
Lazy.Reverse ^= 1;
//>> 更新`Info`;
std::swap( SonPtr[0], SonPtr[1]);
}
}
auto itv = Tr.Get_rootNode_ofInterval( Tr.Get_node_byOrder(), Tr.Get_node_byOrder( i));
Tr.Modify_nodeLazy( itv, {1});
静态翻转(须保证区间端点不会相互干涉)
@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=138138478
;
应用
@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=138138478
;
静态区间翻转;