• P3391 文艺平衡树(Splay做法)


    您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

    其中需要提供以下操作:翻转一个区间,例如原有序序列是 5 4 3 2 15 4 3 2 1,翻转区间是 [2,4][2,4] 的话,结果是 5 2 3 4 15 2 3 4 1。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    const int inf=1e9;
    int n,m;
    struct Splay_tree {
        int fa;
        int cnt;
        int ch[2];
        int v;
        int size;
        int lazy;
    }t[maxn];
    int root,tot;
    void update (int x) {
        t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
    }
    void pushdown (int x) {
        if (t[x].lazy) {
            t[t[x].ch[0]].lazy^=1;
            t[t[x].ch[1]].lazy^=1;
            t[x].lazy=0;
            swap(t[x].ch[0],t[x].ch[1]);
        }
    }
    void rotate (int x) {
        int y=t[x].fa;
        int z=t[y].fa;
        int k=(t[y].ch[1]==x);
        t[z].ch[t[z].ch[1]==y]=x;
        t[x].fa=z;
        t[y].ch[k]=t[x].ch[k^1];
        t[t[x].ch[k^1]].fa=y;
        t[x].ch[k^1]=y;
        t[y].fa=x;
        update(y);
        update(x);
    }
    void splay (int x,int s) {
        while (t[x].fa!=s) {
            int y=t[x].fa;
            int z=t[y].fa;
            if (z!=s) 
                (t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
            rotate(x);
        }
        if (s==0) root=x;
    }
    void find (int x) {
        int u=root;
        if (!u) return;
        while (t[u].ch[x>t[u].v]&&x!=t[u].v) 
            u=t[u].ch[x>t[u].v];
        splay(u,0);
    }
    void ins (int x) {
        int u=root;
        int fa=0;
        while (u&&t[u].v!=x) {
            fa=u;
            u=t[u].ch[x>t[u].v];
        }
        if (u)
            t[u].cnt++;
        else {
            u=++tot;
            if (fa)
                t[fa].ch[x>t[fa].v]=u;
            t[u].ch[0]=t[u].ch[1]=0;
            t[tot].fa=fa;
            t[tot].v=x;
            t[tot].cnt=1;
            t[tot].size=1;
        }
        splay(u,0); 
    }
    int Next (int x,int f) {
        find(x);
        int u=root;
        if (t[u].v>x&&f) return u;
        if (t[u].v<x&&!f) return u;
        u=t[u].ch[f];
        while (t[u].ch[f^1]) u=t[u].ch[f^1];
        return u;
    } 
    void del (int x) {
        int lst=Next(x,0);
        int nxt=Next(x,1);
        splay(lst,0);
        splay(nxt,lst);
        int tt=t[nxt].ch[0];
        if (t[tt].cnt>1) {
            t[tt].cnt--;
            splay(tt,0);
        }
        else 
            t[nxt].ch[0]=0;
    }
    int kth (int x) {
        int u=root;
        while (t[u].size<x) return 0;
        while (1) {
            pushdown(u);
            int y=t[u].ch[0];
            if (x>t[y].size+t[u].cnt) {
                x-=t[y].size+t[u].cnt;
                u=t[u].ch[1];
            }
            else if (t[y].size>=x) 
                u=y;
            else
                return t[u].v;
        }
    }
    void reverse (int l,int r) {
        l=kth(l);
        r=kth(r+2);
        splay(l,0);
        splay(r,l);
        t[t[t[root].ch[1]].ch[0]].lazy^=1; 
    }
    void dfs (int u) {
        pushdown(u);
        if (t[u].ch[0])
            dfs(t[u].ch[0]);
        if (t[u].v>1&&t[u].v<n+2)printf("%d ",t[u].v-1);
        if (t[u].ch[1])
            dfs(t[u].ch[1]);
    }
    int main () {
        scanf("%d%d",&n,&m);
    
        for (int i=1;i<=n+2;i++) ins(i);
        for (int i=1;i<=m;i++) {
            int l,r;
            scanf("%d%d",&l,&r);
            reverse(l,r);
        }
        dfs(root);
    }
  • 相关阅读:
    JSP语法学习笔记
    jsp 自定义标签
    java排序算法
    Linux系统rootpassword改动
    人生中第一次面试——北漂18年(1)
    msgsnd的一个小问题
    推荐系统中的矩阵分解演变方式
    FZU 2124 FOJ 2124 吃豆人【BFS】
    啦啦啦啦、新人学习中。。
    【Linux】线程并发拷贝程序
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13417409.html
Copyright © 2020-2023  润新知