C102 单调栈 P1901 发射站

C102 单调栈 P1901 发射站_哔哩哔哩_bilibili 

Luogu P1901 发射站

// 单调栈 O(n)
#include<bits/stdc++.h>
using namespace std;

const int N=1000005;
int n,h[N],v[N],sum[N]; //sum[i]:每个站接收的能量和

int main(){
  cin>>n;
  for(int i=1;i<=n;i++) cin>>h[i]>>v[i];
  
  int s[N], top=0; //栈维护降序列
  for(int i=1;i<=n;i++){
    while(top && h[s[top]]<h[i]){
      sum[i]+=v[s[top--]]; //i高于栈顶,栈顶的能量给i
    }
    if(top) sum[s[top]]+=v[i]; //i低于栈顶,i的能量给栈顶
    s[++top]=i;
  }
  
  int ans=0;
  for(int i=1;i<=n;i++) ans=max(ans,sum[i]);
  cout<<ans;
}

 

Luogu P1823 [COI2007] Patrik 音乐会的等待

// 单调栈 O(n)
#include<iostream>
using namespace std;

const int N=1000005;
int n,h[N],sum[N]; //sum[i]:i前面未挡的与i等高的人数
long long ans=0;
 
int main(){
  cin>>n;
  for(int i=1;i<=n;i++) cin>>h[i],sum[i]=1;
  
  int s[N], top=0; //栈维护降序列
  for(int i=1;i<=n;i++){
    while(top && h[s[top]]<=h[i]){
      ans+=sum[s[top]]; //i高于栈顶,i能看见栈顶
      if(h[s[top]]==h[i]) sum[i]+=sum[s[top]]; //后面能看见i的,一定能看见前面未挡的等高的
      top--;
    }
    if(top) ans++; //i低于栈顶,栈顶能看见i
    s[++top]=i;
  }
  cout<<ans;
}

 

posted @ 2024-03-16 11:11  董晓  阅读(295)  评论(0)    收藏  举报