zoukankan      html  css  js  c++  java
  • bzoj 1861

    splay裸题嘛...

    直接按书的编号顺序建splay,然后维护即可

    把移动位置变成插入和删除

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    int ch[80005][2];
    int f[80005];
    int a[80005];
    int siz[80005];
    char s[15];
    int rot,tot;
    int n,m;
    void update(int rt)
    {
        siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1;
    }
    void rotate(int x)
    {
        int y=f[x],z=f[y],k=(ch[y][1]==x);
        ch[z][ch[z][1]==y]=x,f[x]=z;
        ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
        ch[x][!k]=y,f[y]=x;
        update(y),update(x);
    }
    void splay(int x,int ed)
    {
        while(f[x]!=ed)
        {
            int y=f[x],z=f[y];
            if(z!=ed)
            {
                if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        if(!ed)rot=x;
    }
    int buildtree(int l,int r,int fa)
    {
        if(l==r){siz[a[l]]=1;f[a[l]]=a[fa];return a[l];}
        int mid=(l+r)>>1;
        f[a[mid]]=a[fa];
        if(l<mid)ch[a[mid]][0]=buildtree(l,mid-1,mid);
        if(r>mid)ch[a[mid]][1]=buildtree(mid+1,r,mid);
        update(a[mid]);
        return a[mid];
    }
    int get_pre(int x)
    {
        splay(x,0);
        int l=ch[x][0];
        while(ch[l][1])l=ch[l][1];
        return l;
    }
    int get_sub(int x)
    {
        splay(x,0);
        int r=ch[x][1];
        while(ch[r][0])r=ch[r][0];
        return r;
    }
    void del(int l,int r)
    {
        splay(l,0),splay(r,l);
        f[ch[r][0]]=0,ch[r][0]=0;
    }
    void ins(int l,int r,int v)
    {
        splay(l,0),splay(r,l);
        ch[r][0]=v,f[v]=r,siz[v]=1;
        update(r),update(l);    
    }
    void push_top(int x)
    {
        int fr=get_pre(x),ed=get_sub(x);
        del(fr,ed);
        int ffr=n+1,eed=get_sub(ffr);
        ins(ffr,eed,x);
    }
    void push_down(int x)
    {
        int fr=get_pre(x),ed=get_sub(x);
        del(fr,ed);
        int eed=n+2,ffr=get_pre(eed);
        ins(ffr,eed,x);
    }
    void push_up(int x)
    {
        int fr=get_pre(x),ed=get_sub(x);
        del(fr,ed);
        int ffr=get_pre(fr);
        ins(ffr,fr,x);
    }
    void push_back(int x)
    {
        int fr=get_pre(x),ed=get_sub(x);
        del(fr,ed);
        int eed=get_sub(ed);
        ins(ed,eed,x);
    }
    void up_and_down(int x)
    {
        int T;
        scanf("%d",&T);
        if(T==-1)push_up(x);
        else if(T==1)push_back(x);
    }
    void query_sum(int x)
    {
        splay(x,0);
        printf("%d
    ",siz[ch[x][0]]-1);
    }
    int query_num(int rt,int k)
    {
        if(siz[ch[rt][0]]>=k)return query_num(ch[rt][0],k);
        else if(k>siz[ch[rt][0]]+1)return query_num(ch[rt][1],k-1-siz[ch[rt][0]]);
        else return rt;
    }
    void Query_num(int x)
    {
        printf("%d
    ",query_num(rot,x+1));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=2;i<=n+1;i++)scanf("%d",&a[i]);
        a[1]=n+1,a[n+2]=n+2;
        rot=buildtree(1,n+2,0);
        while(m--)
        {
            int x,T;
            scanf("%s%d",s,&x);
            if(s[0]=='T')push_top(x);
            else if(s[0]=='B')push_down(x);
            else if(s[0]=='I')up_and_down(x);
            else if(s[0]=='A')query_sum(x);
            else Query_num(x);
        }
        return 0;
    }
  • 相关阅读:
    iOS 循环引用 委托 (实例说明)
    【iOS】自动引用计数 (循环引用)
    有关UITableviewCell 重用内存 内部解析
    通用的类->可直接存储的Dictionary,可以被JSON或NSUserDefaults
    ipa 发布到stroe
    根据当前登录域账号 获取AD用户姓名和所在OU目录
    ASP.NET MVC 操作AD 获取域服务器当前用户姓名和OU信息
    各种图标 资源下载
    【赚】cocos2d-x学习资源汇总(持续更新。。。)
    ios网络层优化深入浅出
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11120039.html
Copyright © 2011-2022 走看看