团体程序设计天梯赛(L3-002 特殊堆栈 (30 分))

题目:

思路分析:

就是在栈的基础上加一个寻找第k大元素的一个功能

1.树状数组实现

树状数组储存的是每个数出现的次数 然后二分查询第k个数首次出现的地方

2.线段树实现 

代码实现:

树状数组

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=100010;
int a[MAX];
int lowbit(int x){
    return x&-x;
}
void updata(int pos,int x){
    while (pos<MAX) {
        a[pos]+=x;
        pos+=lowbit(pos);
    }
}
int getsum(int pos){
    int ans=0;
    while (pos>0) {
        ans+=a[pos];
        pos-=lowbit(pos);
    }
    return ans;
}
int n;
stack<int>st;
void query(){
    int l=1;
    int r=MAX;
    int k=(st.size()+1)/2;
    while (l<r) {
        int mid=(l+r)>>1;
        if(getsum(mid)>=k){
            r=mid;
        }
        else {
            l=mid+1;
        }
    }
    cout<<l<<endl;
}


char c[20];
int main(){
    cin>>n;
    while (n--) {
        cin>>c;
        //pop
        if(c[1]=='o'){
            if(st.empty()){
                cout<<"Invalid"<<endl;
                continue;
            }
            else {
                int x;
                x=st.top();
                updata(x,-1);
                cout<<x<<endl;
                st.pop();
            }
        }
        //push
        else if(c[1]=='u'){
            int x;
            cin>>x;
            st.push(x);
            updata(x,1);
        }
        //fink
        else {
            if(st.empty()){
                cout<<"Invalid"<<endl;
                continue;
            }
            else {
                query();
            }
        }
    }
}

线段树

const int MAX=100010;
int a[MAX<<1];
void updata(int l,int r,int x,int num,int pos){
    if(l==r){
        a[pos]+=num;
        return;
    }
    int mid=r+l>>1;
    if(mid>=x){
        updata(l,mid,x,num,pos<<1);
    }
    else updata(mid+1,r,x,num,pos<<1|1);
    a[pos]=a[pos<<1|1]+a[pos<<1];
}
int query(int l,int r,int x,int pos){
    if(l==r){
        return l;
    }
    int mid=l+r>>1;
    if(a[pos<<1]>=x){
        return query(l,mid,x,pos<<1);
    }
    else
        return query(mid+1,r,x-a[pos<<1],pos<<1|1);
}
stack<int>st;
int main(){
    int n;
    cin>>n;
    while (n--) {
        string s;
        cin>>s;
        if(s[1]=='o'){
            if(st.empty()){
                cout<<"Invalid"<<endl;
            }
            else{
                int x;
                x=st.top();
                st.pop();
                cout<<x<<endl;
                updata(1,MAX,x,-1,1);
            }
        }
        else if(s[1]=='u'){
            int x;
            cin>>x;
            st.push(x);
            updata(1,MAX,x,1,1);
        }
        else{
            if(st.empty()){
                cout<<"Invalid"<<endl;
            }
            else{
                int x;
                x=st.size();
                if(x&1){
                    x++;
                }
                cout<<query(1,MAX,x/2,1)<<endl;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_57006708/article/details/121198393