「luogu2569」[ZJOI2006] 书架

「luogu2569」[ZJOI2006]书架

题目大意

给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五种操作:

  1. \(Top\) \(S\) ——表示把编号为 \(S\) 的书放在最上面;
  2. \(Bottom\) \(S\)——表示把编号为 \(S\) 的书放在最下面;
  3. \(Insert\) \(S\) \(T\)——\(T \in \{-1,0,1\}\),若编号为 \(S\) 的书上面有 \(X\) 本书,则这条命令表示把这本书放回去后它的上面有 \(X+T\) 本书;
  4. \(Ask\) \(S\)——询问编号为 \(S\) 的书的上面目前有多少本书;
  5. \(Query\) \(S\)——询问从上面数起的第 \(S\) 本书的编号。

对于每个 \(Ask\)\(Query\) 操作,输出答案。
(以上摘自luogu)

题解

\(fhq\_treap\) 复健,没有题解。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
inline int in() {
    int x=0;char c=getchar();bool f=false;
    while(c<'0'||c>'9') f|=c=='-', c=getchar();
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48), c=getchar();
    return f?-x:x;
}

const int N = 8e4+5;

int mp[N];

struct fhq_treap {
#define t a[p]
#define lson a[a[p].l]
#define rson a[a[p].r]
    struct node {
        int l, r, key, size, fa, rnd;
    }a[N];
    int tot, rt;

    inline int new_node(int key) {
        a[++tot]=(node){0, 0, key, 1, 0, rand()};
        mp[key]=tot;
        return tot;
    }
    inline void push_up(int p) {
        if(p) {
            t.size=lson.size+rson.size+1;
            lson.fa=rson.fa=p;
        }
    }
    void split(int p, int &x, int &y, int k) {
        if(!p) return (void)(x=y=0);
        if(lson.size<k) x=p, split(t.r, t.r, y, k-lson.size-1);
        else            y=p, split(t.l, x, t.l, k);
        push_up(p);
    }
    int merge(int x, int y) {
        if(!x||!y) return x?x:y;
        int p=0;
        if(a[x].rnd<a[y].rnd) p=x, t.r=merge(t.r, y);
        else                  p=y, t.l=merge(x, t.l);
        push_up(p);
        return p;
    }
    inline int kth_id(int k) {
        int p=rt;
        while(lson.size+1!=k)
            if(lson.size>=k) p=t.l;
            else k-=lson.size+1, p=t.r;
        return a[p].key;
    }
    inline int find_rank(int p) {
        int ret=lson.size+1;
        for(;p!=rt;p=t.fa)
            if(a[t.fa].r==p) ret+=a[a[t.fa].l].size+1;
        return ret;
    }
    void debug(int p) {
        if(t.l) debug(t.l);
        printf(" %d", a[p].key);
        if(t.r) debug(t.r);
    }
#undef t
#undef lson
#undef rson
}T;

int main() {
    srand(20021111);
    char opt[10];
    int n=in(), m=in();
    for(int i=1;i<=n;++i) T.rt=T.merge(T.rt, T.new_node(in()));

    int a, b, c, d, s, t, k;
    while(m--) {
        scanf("%s", opt), s=in();
        if(opt[0]=='T') {
            k=T.find_rank(mp[s]);
            T.split(T.rt, a, b, k);
            T.split(a, a, c, k-1);
            T.rt=T.merge(T.merge(c, a), b);
        }
        else if(opt[0]=='B') {
            k=T.find_rank(mp[s]);
            T.split(T.rt, a, b, k);
            T.split(a, a, c, k-1);
            T.rt=T.merge(a, T.merge(b, c));
        }
        else if(opt[0]=='I') {
            t=in();
            k=T.find_rank(mp[s]);
            if(t>0) {
                T.split(T.rt, a, b, k);
                T.split(a, a, c, k-1);
                T.split(b, b, d, k-T.a[a].size-T.a[c].size+1);
                T.rt=T.merge(T.merge(a, b), T.merge(c, d));
            }
            else if(t<0) {
                T.split(T.rt, a, b, k-1);
                T.split(a, a, c, k-2);
                T.split(b, b, d, k-T.a[a].size-T.a[c].size);
                T.rt=T.merge(T.merge(a, b), T.merge(c, d));
            }
        }
        else if(opt[0]=='A') printf("%d\n", T.find_rank(mp[s])-1);
        else printf("%d\n", T.kth_id(s));
        //T.debug(T.rt);
        //putchar('\n');
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/15owzLy1-yiylcy/p/10574891.html
今日推荐