Loading

题解:洛谷 P1165 日志分析

  • 标签:栈,模拟

题意

对于一个栈,给定三种操作:

  1. 0 x,将 \(x\) 入栈;
  2. 1,出栈,栈空时忽略;
  3. 2,查询当前栈内最大值。

思路

前两个都是栈的基本操作,关键在于查最大值。

每次询问暴力找肯定不行。

如果用一个变量一直记录当前最大值,可以应对入栈,出栈就不行。

这个记录的东西必须 \(O(1)\) 复杂度查最大值,而且可以查历史最大值。

可以发现这就是一个栈。

用两个栈,一个记录数值,一个记最大值。

考虑如何维护第二个栈:

  • 进栈:如果现在 \(x\) 大于栈顶,那 \(x\) 是最大值,进栈,否则不动;
  • 出栈:如果现在的 \(x\) 和当前最大值相等,那出栈,最大值变为历史最大值,否则对答案无影响。

查询时输出第二个栈顶即可。

复杂度 \(O(n)\)

代码

#include<bits/stdc++.h>
#define i64 long long
#define L(a,b,c) for(int i=a;i<=b;i+=c)

using namespace std;
const int N=2e5+5;

int n,op,x,p1,p2,st1[N],st2[N];

void push1(int x){st1[++p1]=x;}
void push2(int x){st2[++p2]=x;}
void pop1(){--p1;}
void pop2(){--p2;}

void solve();

signed main(){
  ios::sync_with_stdio(0);
  
  solve();
  
  return 0;
}

void solve(){
  cin>>n;
  L(1,n,1){
    cin>>op;
    if(op==0){
      cin>>x;
      push1(x);
      if(x>st2[p2]) push2(x);
    }
    else if(op==1){
      if(p1>0){
        if(st1[p1]==st2[p2]) pop2();
        pop1();
      }
    }
    else cout<<st2[p2]<<endl;
  }
}
posted @ 2024-06-29 16:43  jess1ca1o0g3  阅读(142)  评论(0)    收藏  举报