zoukankan      html  css  js  c++  java
  • 文艺平衡树[Splay]

    文艺平衡树[Splay]

    题目

    链接

    题解

    Splay板子题

    结果还调了很久的题,这就是搞文化课的副作用

    显然维护数组下标,使得Splay的中序遍历始终为当前数列

    值得注意:

    旋转时始终要记得更新节点

    注意更新root节点

    每次写都忘.jpg

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 100000 + 10;
    
    inline int read()
    {
        int f=1,x=0;
        char ch;
        do
        {
            ch=getchar();
            if(ch=='-') f=-1;
        }while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    struct Splay
    {
        int ch[MAXN][2];
        int idx;
        int val[MAXN];
        int sz[MAXN];
        int fa[MAXN],root;
        int tag[MAXN];
        inline int chk(int x)
        {
            return x==ch[fa[x]][1];
        }
        inline void pushup(int x)
        {
            sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
        }
        inline void pushdown(int x)
        {
            if(!tag[x]) return;
            tag[ch[x][0]]^=1;
            tag[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
            tag[x]=0;
        }
        inline void rotate(int x)
        {
            int f=fa[x],gf=fa[f];
            int k=chk(x);
            ch[gf][chk(f)]=x;
            fa[x]=gf;
            ch[f][k]=ch[x][k^1];fa[ch[x][k^1]]=f;
            ch[x][k^1]=f;
            fa[f]=x;
            pushup(f);pushup(x);
        }
        inline void splay(int x,int goal)
        {
           
            while(fa[x]!=goal)
            {
                int f=fa[x],gf=fa[f];
                if(gf!=goal)
                {
                    if(chk(x)==chk(f)) rotate(f);
                    else rotate(x);
                }
                rotate(x);
            }
            if(!goal) root=x;
        }
        inline int kth(int k)
        {
            int cur=root;
            while(1)
            {
                pushdown(cur);
                if(sz[ch[cur][0]]>=k) cur=ch[cur][0];
                else if(sz[ch[cur][0]]+1==k) return cur;
                else k-=sz[ch[cur][0]]+1,cur=ch[cur][1];
            }
        }
        inline void insert(int x)
        {
            int cur=root,f=0;
            while(cur&&val[cur]!=x)
            {
                f=cur;
                if(val[cur]>x) cur=ch[cur][0];
                else cur=ch[cur][1];
            }
            cur=++idx;
            if(f) ch[f][val[f]<x]=x;
            sz[cur]=1;
            ch[cur][0]=ch[cur][1]=0;
            val[cur]=x;fa[cur]=f;
            if(!root) root=cur; 
            splay(cur,0);
    
        }
    }tree;
    
    int n,m;
    
    inline void update(int l,int r)
    {
        l=tree.kth(l);
        r=tree.kth(r+2);
        tree.splay(l,0);
        tree.splay(r,l);
        tree.tag[tree.ch[tree.ch[l][1]][0]]^=1;
    }
    
    inline void dfs(int cur)
    {
        tree.pushdown(cur);
        if(tree.ch[cur][0]) dfs(tree.ch[cur][0]);
        if(tree.val[cur]>1&&tree.val[cur]<n+2) printf("%d ",tree.val[cur]-1);
        if(tree.ch[cur][1]) dfs(tree.ch[cur][1]);
        return;
    }
    
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n+2;i++) 
        {
            tree.insert(i);
        }
        for(int i=1;i<=m;i++)
        {
            int l=read(),r=read();
            update(l,r);
        }
        dfs(tree.root);
    }
  • 相关阅读:
    RQNOJ 342 最不听话的机器人:网格dp
    RQNOJ 329 刘翔!加油!:01背包
    RQNOJ 57 找啊找啊找GF:01背包
    RQNOJ 202 奥运火炬登珠峰:01背包
    RQNOJ 201 奥运大包围:LIS + 拼链成环
    2017SN多校D1T2 note:dp
    2017SN多校D1T1 loveletter:模拟
    HDU 2157 How many ways??:矩阵快速幂【i到j共经过k个节点的方法数】
    poj 3764 The xor-longest Path
    bzoj 1192 鬼谷子的钱袋
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/11166299.html
Copyright © 2011-2022 走看看