luogu2596 [ZJOI2006]书架

treap。树是以“优先级”(优先级越小,在书架上越靠上)形成的,堆是以rand()的权值形成的。还要再维护一个原编号。
置顶/置底:找到那个元素,把它拉出来修改优先级再塞回去。
insert:即一个元素和他“附近”的元素交换位置,把他们两个拉出来,交换优先级再塞回去

#include 
#include 
#include 
using namespace std;
int n, m, minn, maxn, a[80005], uu, rot, vv, cnt;
char ss[15];
struct Treap{
    int val[200005], rnd[200005], l[200005], r[200005], siz[200005];
    int bh[200005];
    void upd(int x){
        siz[x] = siz[l[x]] + siz[r[x]] + 1;
    }
    void lRotate(int &k){
        int t=r[k]; r[k] = l[t]; l[t] = k;
        siz[t] = siz[k]; upd(k); k = t;
    }
    void rRotate(int &k){
        int t=l[k]; l[k] = r[t]; r[t] = k;
        siz[t] = siz[k]; upd(k); k = t;
    }
    void insert(int &k, int b){
        if(!k){
            k = ++cnt; val[k] = a[b]; bh[k] = b;
            rnd[k] = rand(); siz[k] = 1;
            return ;
        }
        siz[k]++;
        if(val[k]a[b])
            siz[k]--, shanchu(l[k], b);
        else
            siz[k]--, shanchu(r[k], b);
    }
    int queryRank(int k, int b){
        if(!k)  return 0;
        if(a[b]val[k])    return queryRank(r[k], b)+siz[l[k]]+1;
        else    return siz[l[k]]+1;
    }
    int queryNum(int k, int b){
        if(!k)  return 0;
        if(b<=siz[l[k]])    return queryNum(l[k], b);
        else if(b>siz[l[k]]+1)  return queryNum(r[k], b-siz[l[k]]-1);
        else    return bh[k];
    }
}treap;
int main(){
    cin>>n>>m;
    minn = 1; maxn = n;
    for(int i=1; i<=n; i++){
        scanf("%d", &uu);
        a[uu] = i;
        treap.insert(rot, uu);
    }
    while(m--){
        scanf("%s %d", ss, &uu);
        if(ss[0]=='T'){
            treap.shanchu(rot, uu);
            a[uu] = --minn;
            treap.insert(rot, uu);
        }
        if(ss[0]=='B'){
            treap.shanchu(rot, uu);
            a[uu] = ++maxn;
            treap.insert(rot, uu);
        }
        if(ss[0]=='I'){
            scanf("%d", &vv);
            if(vv==0)   continue;
            int t=treap.queryRank(rot, uu);
            int q=treap.queryNum(rot, t+vv);
            treap.shanchu(rot, uu);
            treap.shanchu(rot, q);
            swap(a[uu], a[q]);
            treap.insert(rot, uu);
            treap.insert(rot, q);
        }
        if(ss[0]=='A')
            printf("%d\n", treap.queryRank(rot, uu)-1);
        if(ss[0]=='Q')
            printf("%d\n", treap.queryNum(rot, uu));
    }
    return 0;
}

转载于:https://www.cnblogs.com/poorpool/p/8383628.html

你可能感兴趣的:(luogu2596 [ZJOI2006]书架)