zoukankan      html  css  js  c++  java
  • BZOJ_3223: Tyvj 1729 文艺平衡树 _splay

    题意: 

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

    分析:

    splay维护区间操作的模板题。

    节点维护区间信息。

    提取区间:把l-1旋到根,再把r+1旋到根的右儿子,那么根的右儿子的左子树则是我们需要的区间。

    建树:递归建树,左儿子还是右儿子取决于在当前区间的位置。

    区间反转:打标记的思想,每个标记只对儿子生效。

    其他:建两个哨兵节点来保护1和n

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 100050
    int ch[N][2],f[N],siz[N],val[N];
    int rt,sz,n,m,tag[N];
    void clear(int x){ ch[x][0]=ch[x][1]=f[x]=siz[x]=val[x]=0; }
    int get(int x){ return ch[f[x]][1]==x; }
    void up(int x){ if(x)siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
    void pud(int x){ if(!tag[x])return ;tag[x]=0;swap(ch[x][0],ch[x][1]);tag[ch[x][0]]^=1;tag[ch[x][1]]^=1; }
    void rotate(int x)
    {
        int y=f[x],z=f[y],k=get(x);
        ch[y][k]=ch[x][k^1];f[ch[y][k]]=y;ch[x][k^1]=y;f[y]=x;f[x]=z;
        if(z) ch[z][ch[z][1]==y]=x; up(y),up(x);
        if(rt==y)rt=x;
    }
    void splay(int x,int y)
    {
        for(int fa;(fa=f[x])!=y;rotate(x))
            if(f[fa]!=y)
                rotate((get(x)==get(fa)) ? fa : x);
    }
    int find(int x)
    {
        int now=rt;
        while(1)
        {
            pud(now);
            if(x<=siz[ch[now][0]])now=ch[now][0];
            else
            {
                x-=siz[ch[now][0]]+1;
                if(!x)return now;
                now=ch[now][1];
            }
        }
    }
    void build(int fa,int l,int r)
    {
        if(l>r)return ;
        int mid = l + r >> 1;
        ch[fa][mid > fa] = mid;
        siz[mid] = 1;
        val[mid] = mid - 1;
        f[mid] = fa;
        build(mid, l, mid - 1);
        build(mid, mid + 1, r);
        up(mid);
    }
    void reverse(int x,int y)
    {
        x=find(x);
        y=find(y);
        splay(x,f[rt]);
        splay(y,rt);    
        tag[ch[y][0]]^=1;
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        int i,x,y;
        build(0,1,n+2);
        rt=n+3>>1;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            reverse(x,y+2);
        }
        for(i=2;i<=n;i++) printf("%d ",val[find(i)]);
        printf("%d",val[find(n+1)]);
    }
    
  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/suika/p/8592872.html
Copyright © 2011-2022 走看看