[线段树|平衡树|树状数组]LightOJ - 1087 - Diablo

来源:互联网 发布:中国人均gdp 知乎 编辑:程序博客网 时间:2024/06/03 14:51
1087 - Diablo
PDF (English)StatisticsForum
Time Limit: 2 second(s)Memory Limit: 64 MB

All of you must have played the game 'Diablo'. It's an exclusive game to play. In this game the main opponent of you is Diablo. If you kill him the game finishes. But as usual, Diablo is smarter than you.

Diablo has a large number of army. Diablo arranges them in a line in any arbitrary order and everyone is given an integer id. Each time Diablo either adds one army in the end or he calls for the kth army (from left) from the line. Then the army gets out and it attacks you.

Since you are a great magician, you can read Diablo's mind. Now you want to find the id of the armies who are about to attack you.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

The first line of each case is a blank line. The next line contains two integers n (0 ≤ n ≤ 105), denoting the number of the initial army and q (1 ≤ q ≤ 50000) representing the number of queries. The next line contains n space separated integers. The ith integer of this line denotes the id of the ith person. Each of these integers will be positive and fits into a 32 bit signed integer. Each of the next q lines will contain a query, of the form:

a p    (add a person at the end of the line whose id is p)

c k    (call the kth person from the line (from left), k is a positive 32 bit signed integer)

Output

For each case of input, print the case number in a line. Then for all the queries 'c k' you have to print the id of the kth person or 'none' if there is none.

Sample Input

Output for Sample Input

2

 

5 5

6 5 3 2 1

c 1

c 1

a 20

c 4

c 4

 

2 1

18811 1991

c 1

Case 1:

6

5

20

none

Case 2:

18811


看完题立马想到平衡树,以数的插入顺序建立一颗平衡树,查询和删除第K小即可,然后又想到维护一个区间和,二分求出区间和为k的位置,然后该位置的数就是所求,这种方法可以用线段树或者树状数组实现,不多说了,水题直接上代码。

各种蛋疼:好久没写这些数据结构了,手好生啊,调了半天。

平衡树版本-SBT

#include<iostream>#include<algorithm>#include<queue>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 111111;struct TNode{    int l,r,idx,val,size;    void clearNode(){        l = r = size = 0;    }    void initNode(int idx,int val){        this->idx = idx, this->val = val;        l = r = 0; size = 1;    }};struct SBT{    TNode Node[MAXN];    int pool[MAXN],top,cnt,rt;    void init(){        top = cnt = rt = 0;    }    int Malloc(int id,int v){        int x;        if(top!=0){            x = pool[--top];        }else{            x = ++cnt;        }        Node[x].initNode(id,v);        return x;    }    void Free(int x){        pool[top++] = x;        Node[x].clearNode();    }    void left_rotate(int &p){        TNode &fa = Node[p];        TNode &son = Node[fa.r];        int q = fa.r;//node idx of son        fa.r = son.l; son.l = p;        son.size = fa.size;        fa.size = Node[fa.l].size+Node[fa.r].size+1;        p = q;    }    void right_rotate(int &p){        TNode &fa = Node[p];        TNode &son = Node[fa.l];        int q = fa.l;        fa.l = son.r, son.r = p;        son.size = fa.size;        fa.size = Node[fa.l].size+Node[fa.r].size+1;        p = q;    }    void Maintain(int &p,bool flag){        TNode cur = Node[p];        if(!flag){            if(Node[Node[cur.l].l].size>Node[cur.r].size){                right_rotate(p);            }else if(Node[Node[cur.l].r].size>Node[cur.r].size){                left_rotate(cur.l);                right_rotate(p);            }else{                return;            }        }else{            if(Node[Node[cur.r].r].size>Node[cur.l].size){                left_rotate(p);            }else if(Node[Node[cur.r].l].size>Node[cur.l].size){                right_rotate(cur.r);                left_rotate(p);            }else{                return;            }        }        Maintain(cur.l,0);        Maintain(cur.r,1);        Maintain(p,0);        Maintain(p,1);    }    void Insert(int &p,int idx,int val){        if(!p){            p = Malloc(idx,val);            return;        }else{            Node[p].size++;            if(idx<Node[p].idx)Insert(Node[p].l,idx,val);            else Insert(Node[p].r,idx,val);            Maintain(p,idx>=Node[p].idx);        }    }    int Delete(int &p,int idx){        Node[p].size--;        if(Node[p].idx==idx||(Node[p].l==0&&idx<Node[p].idx)||(Node[p].r==0&&idx>Node[p].idx)){            int q = p;            if(Node[p].l==0||Node[p].r==0){                p = Node[p].l+Node[p].r;                Node[q].clearNode();                return q;            }else{                int cur = Delete(Node[p].r,idx+1);                int tidx = Node[p].idx, tval = Node[p].val;                Node[p].idx = Node[cur].idx, Node[p].val = Node[cur].val;                Node[cur].idx = tidx, Node[cur].val = tval;                return cur;            }        }        if(idx<Node[p].idx)return Delete(Node[p].l,idx);        else return Delete(Node[p].r,idx);    }    int Select(int p,int k){        int rank = Node[Node[p].l].size+1;        if(rank==k)return p;        else if(rank<k)return Select(Node[p].r,k-rank);        else return Select(Node[p].l,k);    }}T;int main(){    int Tot,N,Q,IDX,val;    scanf("%d",&Tot);    for(int cas=1;cas<=Tot;cas++){        T.init();        scanf("%d%d",&N,&Q);        IDX = 0;        while(N--){            scanf("%d",&val);            T.Insert(T.rt,IDX++,val);        }        printf("Case %d:\n",cas);        while(Q--){            char op[3];            scanf("%s%d",op,&val);            if(op[0]=='c'){                if(T.Node[T.rt].size<val){                    printf("none\n");                }else{                    int x = T.Select(T.rt,val);                    x = T.Delete(T.rt,T.Node[x].idx);                    printf("%d\n",T.Node[x].val);                }            }else{                T.Insert(T.rt,IDX++,val);            }        }    }    return 0;}


线段树版本:

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int MAXN = 111111;const int BD = MAXN+50000;int sum[(BD)<<2],record[BD];void build(int l,int r,int rt){    sum[rt]=0;    if(l==r)return;    int m = (l+r)>>1;    build(lson); build(rson);}void update(int pos,int c,int l,int r,int rt){    if(l==r){        //cout<<l<<" "<<c<<" "<<sum[rt]<<endl;        sum[rt]=c;        return;    }    int m = (l+r)>>1;    if(pos<=m)update(pos,c,lson);    else update(pos,c,rson);    sum[rt] = sum[rt<<1]+sum[rt<<1|1];}int query(int k,int l,int r,int rt){    if(l==r)return l;    int m = (l+r)>>1;    if(sum[rt<<1]>=k)return query(k,lson);    else return query(k-sum[rt<<1],rson);}int main(){    int T,N,Q,M;    scanf("%d",&T);    for(int cas=1;cas<=T;cas++){        scanf("%d%d",&N,&Q);M = N+1;        build(1,BD,1);        for(int i=1;i<=N;i++)scanf("%d",&record[i]),update(i,1,1,BD,1);        printf("Case %d:\n",cas);        while(Q--){            char op[3];            int k;            scanf("%s%d",op,&k);            //cout<<"tot:"<<sum[1]<<endl;system("pause");            if(op[0]=='c'){                if(sum[1]<k){                    printf("none\n");                }else{                    int pos = query(k,1,BD,1);//cout<<pos<<" "<<endl;                    //system("pause");                    update(pos,0,1,BD,1);                    printf("%d\n",record[pos]);                }            }else{                record[M] = k;                update(M,1,1,BD,1);                M++;            }        }    }    return 0;}


 

树状数组版本:

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int MAXN = 155555;int sum[MAXN+1],arr[MAXN];int lowbit(int x){    return x&(-x);}int query(int pos){    int s = 0;    while(pos>0){        s+=sum[pos];        pos -= lowbit(pos);    }    return s;}void add(int pos,int c){    while(pos<=MAXN){        sum[pos]+=c;        pos += lowbit(pos);    }}int main(){    int T,N,Q,M,CNT;    scanf("%d",&T);    for(int cas=1;cas<=T;cas++){        scanf("%d%d",&N,&Q);M = N+1;CNT = N;        memset(sum,0,sizeof(sum));        for(int i=1;i<=N;i++){            scanf("%d",&arr[i]);            add(i,1);        }        printf("Case %d:\n",cas);        while(Q--){            char op[3];int k;            scanf("%s%d",op,&k);            //cout<<query(MAXN)<<endl;system("pause");            if(op[0]=='c'){                if(CNT<k){                    printf("none\n");                    continue;                }                CNT--;                int l = 1,r = MAXN,m;                while(l<=r){                    m = (l+r)>>1;                    if(k<=query(m))r = m-1;                    else l = m+1;                }                //cout<<l<<" "<<query(l)<<endl;system("pause");                printf("%d\n",arr[l]);                add(l,-1);            }else{                CNT++;                arr[M] = k;                add(M++,1);            }        }    }    return 0;}


 

原创粉丝点击