算法 {区间翻转}

算法 {区间翻转}

区间翻转

定义

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;
静态区间翻转;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值