【CCCC】L3-002 特殊堆栈 (30分),nlogn维护序列中位数,STL大乱斗,有重multiset,vector+二分插入

    科技2024-01-09  67

    problem

    L3-002 特殊堆栈 (30分) 堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 N 个元素,如果 N 是偶数,则中值定义为第 N/2 小元;若是奇数,则为第 (N+1)/2 小元。

    输入格式: 输入的第一行是正整数 N(≤10 ​5 ​​ )。随后 N 行,每行给出一句指令,为以下 3 种之一:

    Push key Pop PeekMedian 其中 key 是不超过 10 ​5 ​​ 的正整数;Push 表示“入栈”;Pop 表示“出栈”;PeekMedian 表示“取中值”。

    输出格式: 对每个 Push 操作,将 key 插入堆栈,无需输出;对每个 Pop 或 PeekMedian 操作,在一行中输出相应的返回值。若操作非法,则对应输出 Invalid。

    输入样例: 17 Pop PeekMedian Push 3 PeekMedian Push 2 PeekMedian Push 1 PeekMedian Pop Pop Push 5 Push 4 PeekMedian Pop Pop Pop Pop 输出样例: Invalid Invalid 3 2 2 1 2 4 4 5 3 Invalid

    problem

    维护一个栈(1e5),支持pop,push和取中间值(第n/2小元)即需要nlogn的维护中位数,想到了multiset,但是迭代器输出会TLE可以用vector+二分插入 //AC #include<bits/stdc++.h> using namespace std; const int maxn = 10010; stack<int>stk; //multiset<int>se; vector<int>order; int main(){ int T; cin>>T; while(T--){ string s; cin>>s; int re = 0; if(s=="Push"){ int x; cin>>x; stk.push(x); order.insert(lower_bound(order.begin(), order.end(), stk.top()), stk.top()); } if(s=="Pop"){ if(stk.size()){ cout<<stk.top()<<"\n"; order.erase(lower_bound(order.begin(), order.end(), stk.top())); stk.pop(); }else{ re = 1; } } if(s=="PeekMedian"){ if(stk.size()){ //cout<<stk.size()<<" "; cout<<order[(stk.size()-1)/2]<<endl; }else{ re = 1; } } if(re)cout<<"Invalid\n"; } return 0; } //TLE - multiset #include<bits/stdc++.h> using namespace std; const int maxn = 10010; stack<int>stk; multiset<int>se; int main(){ //freopen("ans.cpp","r",stdin); int T; cin>>T; while(T--){ string s; cin>>s; int re = 0; if(s=="Push"){ int x; cin>>x; stk.push(x); se.insert(x); } if(s=="Pop"){ if(stk.size()){ cout<<stk.top()<<"\n"; //se.erase(stk[top]); WA4,会删掉所有元素 multiset <int>::iterator pos = se.find(stk.top()); se.erase(pos); stk.pop(); }else{ re = 1; } } if(s=="PeekMedian"){ if(stk.size()){ int tt = (stk.size()+1)/2; multiset<int>::iterator it = se.begin(); for(int i = 1; i < tt; i++)it++; cout<<(*it)<<"\n"; //cout<<stk[(top+1)/2]<<"\n"; }else{ re = 1; } } if(re)cout<<"Invalid\n"; } return 0; } //TLE- stack #include<bits/stdc++.h> using namespace std; const int maxn = 100010; int stk[maxn], top; multiset<int>se; int main(){ //freopen("ans.cpp","r",stdin); int T; cin>>T; while(T--){ string s; cin>>s; int re = 0; if(s.size()==4){ int x; cin>>x; stk[++top] = x; se.insert(x); } if(s.size()==3){ if(top>=1){ cout<<stk[top]<<"\n"; //se.erase(stk[top]); WA4,会删掉所有元素 multiset <int>::iterator pos = se.find(stk[top]); se.erase(pos); top--; }else{ re = 1; } } if(s=="PeekMedian"){ if(top>=1){ int tt = (top+1)/2; multiset<int>::iterator it = se.begin(); for(int i = 1; i < tt; i++)it++; cout<<(*it)<<"\n"; //cout<<stk[(top+1)/2]<<"\n"; }else{ re = 1; } } if(re)cout<<"Invalid\n"; } return 0; }
    Processed: 0.009, SQL: 8