• [模板] 文艺平衡树


    文艺平衡树就是splay,维护区间反转,就是把所有左变成右,打个标记就好啦.一开始智障判断是否为根节点的时候傻乎乎的判断是否等于0...删了就好啦!

    题干:

    题目描述
    
    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
    输入输出格式
    输入格式:
    
    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2,⋯n−1,n) (1,2, cdots n-1,n)(1,2,⋯n−1,n) m表示翻转操作次数
    
    接下来m行每行两个数 [l,r][l,r][l,r] 数据保证 1≤l≤r≤n 1 leq l leq r leq n 1≤l≤r≤n
    
    输出格式:
    
    输出一行n个数字,表示原始序列经过m次变换后的结果

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #define B cout << "Breakpoint!" << endl;
    #define O(a) cout << #a << " " << a << endl;
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    int N,M,tot = 0;
    int root = 0;
    struct node
    {
        int ch[2],f,v;
        int siz,mark;
        void init(int x,int fa)
        {
            f = ch[0] = ch[1] = 0;
            siz = 1;v = x;
            f = fa;
        }
    }e[200010];
    //#define root e[1].ch[1]
    inline void update(int x)
    {
        e[x].siz = e[e[x].ch[0]].siz + e[e[x].ch[1]].siz + 1;
    }
    inline void pushdown(int x)
    {
        if(e[x].mark)
        {
            e[e[x].ch[0]].mark ^= 1;
            e[e[x].ch[1]].mark ^= 1;
            e[x].mark = 0;
            swap(e[x].ch[0],e[x].ch[1]);
        }
    }
    inline int iden(int x)
    {
        return e[e[x].f].ch[0] == x ? 0 : 1;
    }
    inline void connect(int x,int f,int son)
    {
        e[x].f = f;
        e[f].ch[son] = x;
    }
    inline void rotate(int x)
    {
        int y = e[x].f;
        int mroot = e[y].f;
        int mrootson = iden(y);
        int yson = iden(x);
        int b = e[x].ch[yson ^ 1];
        connect(b,y,yson);
        connect(y,x,yson ^ 1);
        connect(x,mroot,mrootson);
        update(y);
        update(x);
    }
    /*inline void splay(int at,int to)
    {
        while(e[at].f != to)
        {
            // O(e[at].f);
            // O(to);
            int y = e[at].f;
            int z = e[to].f;
            cout<<y<<" "<<z<<endl;
            if(z != to)
            rotate(at);
            else
            rotate(to);
            rotate(at);
        }
        if(to == 0) root = at;
        cout<<root<<endl;
    }*/
    inline void splay(int at,int to)
    {
        while(e[at].f != to)
        {
            int up = e[at].f;
            if(e[up].f == to) rotate(at);
            else if(iden(up) == iden(at))
            {
                rotate(up);
                rotate(at);
            }
            else
            {
                rotate(at);
                rotate(at);
            }
        }
        if(to == 0) root = at;
        // cout<<root<<endl;
    }
    inline void insert(int x)
    {
        int u = root,ff = 0;
        while(u)
        {
            ff = u;
            u = e[u].ch[x > e[u].v];
        }
        u = ++tot;
        // cout<<x<<" "<<ff<<endl;
        if(ff) e[ff].ch[x > e[ff].v] = u;
        e[u].init(x,ff);
        splay(u,0);
    }
    inline int kth(int k)
    {
        int u = root;
        // cout<<"!!!"<<u<<endl;
        while(1)
        {
            pushdown(u);
            if(e[e[u].ch[0]].siz >= k) u = e[u].ch[0];
            else if(e[e[u].ch[0]].siz + 1 == k)
            {
                // cout<<u<<endl;
                return u;
            }
            else
            {
                k -= e[e[u].ch[0]].siz + 1;
                u = e[u].ch[1];
            }
        }
    }
    void write(int u)
    {
        pushdown(u);
        if(e[u].ch[0]) write(e[u].ch[0]);
        if(e[u].v > 1 && e[u].v < N + 2)
        printf("%d ",e[u].v - 1);
        if(e[u].ch[1]) write(e[u].ch[1]);
    }
    inline void work(int l,int r)
    {
        l = kth(l);
        r = kth(r + 2);
        splay(l,0);
        splay(r,l);
        e[e[e[root].ch[1]].ch[0]].mark ^= 1;
    }
    int main()
    {
        // freopen("in.in","r",stdin);
        read(N);read(M);
        duke(i,1,N + 2)
        insert(i);
        /*duke(i,1,N + 2)
        {
            printf("%d %d %d
    ",e[i].ch[0],e[i].ch[1],e[i].v);
        }*/
        while(M--)
        {
            int l,r;
            read(l);read(r);
            work(l,r);
            /*duke(i,1,N + 2)
            {
                printf("%d %d %d
    ",e[i].ch[0],e[i].ch[1],e[i].v);
            }*/
        }
        /*puts("");
        duke(i,1,N + 2)
        {
            printf("%d %d %d
    ",e[i].ch[0],e[i].ch[1],e[i].v);
        }*/
        write(root);
        puts("");
        return 0;
    }
  • 相关阅读:
    Java中编写代码出现异常,如何抛出异常,如何捕获异常
    用Java制作斗地主
    Java—Map接口中的常用方法
    Java—增强for循环与for循环的区别/泛型通配符/LinkedList集合
    Java—包装类/System类/Math类/Arrays类/大数据运算/Collection接口/Iterator迭代器
    Java—时间的原点 计算时间所使用的 Date类/DateFormat类/Calendar类
    Java—匿名对象/内部类/访问修饰符/代码块
    Java—构造方法及this/super/final/static关键字
    Java—接口
    URL Protocol打开应用程序并传递程序启动参数(Windows、Mac)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10036562.html
Copyright © 2020-2023  润新知