poj1442 Black Box treap

     N个数,在插入第B[i]个数之后,查询当前集合中第i小的数是多少。treap模板题...

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int maxn=101000;
int pre[maxn];
int ch[maxn][2];
int size[maxn];
int ct[maxn];
int pri[maxn];
int key[maxn];
int tot,root;
int cmp(int a,int b)
{
    if (a==b) return -1;
    if (a<b) return 0;
    else return 1;
}

struct TREAP
{
    void init()
    {
        root=0;
        memset(pre,0,sizeof pre);
        memset(ch,0,sizeof ch);
        memset(ct,0,sizeof ct);
        memset(size,0,sizeof size);
        tot=0;
    }
    void pushup(int r)
    {
        size[r]=size[ch[r][0]]+size[ch[r][1]]+ct[r];
    }

    void rotate(int x,int kind)
    {
        int k=ch[x][kind^1];
        ch[x][kind^1]=ch[k][kind];
        pre[ch[k][kind]]=x;
        ch[k][kind]=x;
        pre[k]=pre[x];
        if (pre[x])
        {
            ch[pre[x]][ch[pre[x]][1]==x]=k;
        }
        else root=k;
        pre[x]=k;
        pushup(x);
        pushup(k);
    }

    void newnode(int &r,int father,int k)
    {
        r=++tot;
        pre[r]=father;
        pri[r]=rand();
        size[r]=1;
        ct[r]=1;
        key[r]=k;
        ch[r][0]=ch[r][1]=0;
    }

    void insert(int &rt,int x,int father)
    {
        if (rt==0)
        {
            newnode(rt,father,x);
        }
        else
        {
            int d=cmp(x,key[rt]);
            if (d==-1)
            {
                ct[rt]++;
                size[rt]++;
            }
            else
            {
                insert(ch[rt][d],x,rt);
                pushup(rt);
                if (pri[ch[rt][d]]>pri[rt]) rotate(rt,d^1);
            }
        }
    }
    void print(int r)
    {
        if (r==0) return;
        print(ch[r][0]);
        for (int i=1; i<=ct[r]; i++)
        printf("%d ",key[r]);
        print(ch[r][1]);
    }
    void printpri(int r)
    {
        if (r==0) return;
        print(ch[r][0]);
        printf("%d ",pri[r]);
        print(ch[r][1]);
    }
    int select(int k)
    {
        int rt=root;
        while(true)
        {
            if (k<=size[ch[rt][0]]) rt=ch[rt][0];
            else if (k<=size[ch[rt][0]]+ct[rt]) break;
            else k-=(size[ch[rt][0]]+ct[rt]),rt=ch[rt][1];
        }
        return rt;
    }
}treap;
int n,m;
int a[100600];
int b[100600];
int main()
{
//    freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        treap.init();
        for (int i=1; i<=n; i++)
        scanf("%d",&a[i]);
        for (int i=1; i<=m; i++)
        scanf("%d",&b[i]);
        int pt=1;
        for (int i=1; i<=n; i++)
        {
            treap.insert(root,a[i],0);
//            treap.print(root);
//            puts("");
            while (i==b[pt])
            {
                int ans=treap.select(pt);
                cout<<key[ans]<<endl;
//                treap.del(ans);
//                treap.insert(root,key[ans]+1,0);
                pt++;
            }
        }

    }
    return 0;
}


你可能感兴趣的:(poj1442 Black Box treap)