P3391 【模板】文艺平衡树

· · 题解

FHQ_treap(码量小超好理解)

修改了一些错别字,管理员求通过

如果不会用FHQ做P3369的请左转

前言:总感觉这么做没有那么强平衡树的感觉(我太菜了),因为作为权值的pos并没有在程序中直接体现,但好好想想也可以理解以size为比较方案的Split。因此会以此比较方案及其原因作为重点

注意: 与P3369普通平衡树的区别

函数 在普通平衡树中 在文艺平衡树中
Split 以v作为比较方案 以size作为比较方案,v只作为该节点在原序列中对应的值
Merge 直接合 先要把翻转标记下传
pushdown 如果自己标记为1,把自己标记清空,把标记^给两个儿子,换一下左右儿子

Split理解

void split(int now,int &a,int &b,int k){
    if(now==0){a=0;b=0;return;}
    pushdown(now);
    if(si[t[now][0]]<k){
        a=now;
        split(t[now][1],t[now][1],b,k-si[t[now][0]]-1);
    }
    else{
        b=now;
        split(t[now][0],a,t[now][0],k);
    }
    pushup(now);
}

感觉怪怪的?

最后,因为是以pos为权值(虽然未直接体现)的平衡树,且v[]表示该节点对应序列中的值,直接从root中序遍历输出v即可

各数组意义