[Luo Gu P3391] [template] literary balanced tree (Splay)

Title Description: https://www.luogu.org/problemnew/show/P3391

 

Analysis: Here to talk about the main point of view of the weight of the splay. First, we found a splay of preorder is always the same, so the thought of a preorder splay to represent the position of the original array. So how to achieve it? We need only just started achievements when the position is the weight to achievements. Put another way, just to make contribution to the position in order splay traversal order. So in fact, Fengyun splay any course is the number of the original array of weights, is only just beginning achievements achievements when a change of the way. So some students might ask, after the swap does not meet the large splay left and right small nature yet? Certainly not satisfied ah. Some students may ask another question, how to ensure the r + 1 will be able to rotate to the right of the son go l-1, have been satisfied with the nature of splay is not it? Note, splay rotation operation is nothing to do with weight point, it's just a tree with splay how to build a relationship.

    Attach codes (original array of Origin):

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN=100005;
int n,m;
int root;
struct Node{
    int size,son[2],val,fa,tag;
}node[MAXN];
int ndnum=0;
int origin[MAXN];

int check(int x){
    return x==node[node[x].fa].son[1];
}

void update(int x){
    node[x].size=node[node[x].son[0]].size+node[node[x].son[1]].size+1;
}

void rotate(int x){
    int y=node[x].fa,z=node[y].fa,d=check(x),xx=node[x].son[d^1];
    node[y].son[d]=xx;node[xx].fa=y;
    node[z].son[check(y)]=x;node[x].fa=z;
    node[x].son[d^1]=y;node[y].fa=x;
    update(y);update(x);
} 

void splay(int x,int to=0){
    while(node[x].fa!=to){
        int y=node[x].fa,z=node[y].fa;
        if(z!=to){
            if(check(x)==check(y)) rotate(y);
            else rotate(x);
        }    
        rotate(x);
    }
    if(!to) root=x;
}

void insert(int x){
    int cur=root,f=0;
    while(cur&&node[cur].val!=x){
        f=cur;
        cur=node[cur].son[x>node[cur].val];
    }
    cur=++ndnum;
    if(f) node[f].son[x>node[f].val]=cur;
    node[cur].size=1;node[cur].tag=0;
    node[cur].son[0]=node[cur].son[1]=0;
    node[cur].val=x;node[cur].fa=f;
    splay(cur);
}

void pushdown(int cur){
    if(node[cur].tag){
        node[node[cur].son[0]].tag^=1;
        node[node[cur].son[1]].tag^=1;
        node[cur].tag=0;
        swap(node[cur].son[0],node[cur].son[1]);
    }
}

int kth(int k){
    int cur=root;
    while(1){
        pushdown(cur);
        if(k<=node[node[cur].son[0]].size)
        cur=node[cur].son[0];
        else{
            k-=node[node[cur].son[0]].size+1;
            if(!k) return cur;
            cur=node[cur].son[1];
        } 
    }
} 

void reserve(int l,int r){
    l=kth(l-1);r=kth(r+1);
    splay(l);splay(r,l);
    node[node[node[root].son[1]].son[0]].tag^=1;
}

void write(int cur){
    pushdown(cur);
    if(node[cur].son[0]) write(node[cur].son[0]);
    if(node[cur].val>1&&node[cur].val<n+2) printf("%d ",origin[node[cur].val-1]);
    if(node[cur].son[1]) write(node[cur].son[1]);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&origin[i]); 
    for(int i=1;i<=n+2;i++) insert(i);
    for(int i=1;i<=m;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        reserve(l+1,r+1);
    }
    write(root);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/JoshDun/p/11183043.html