[USACO06NOV]糟糕的一天Bad Hair Day

一些农民约翰的N头牛(1≤N≤80,000)头发不好!由于每头母牛都对自己的发型很敏感,因此FJ想要计算能够看到其他母牛头顶的其他母牛的数量。
每头牛都有一个特定的高度hi(1≤hi≤1,000,000,000),站在一排朝东的牛群中。因此,只要这些奶牛严格比奶牛矮,i就可以看到奶牛头顶上的奶牛(即母牛i + 1,i + 2等等)。

考虑每个点对答案的贡献。
设他右边比他高的第一个点为k,点i对答案的贡献为 k-i-1。
答案即为求 kii1(1<=i<=n) ∑ k i − i − 1 ( 1 <= i <= n )
找到他右边第一个比他高的点,我们倒序就变成了找左边比他高的点,维护单调下降的单调栈即可。

#include<bits/stdc++.h>
using namespace std;

const int MAXN=3e5+5;
const int INF=2147483647;

int top=0,n;
struct data{
    int val,tim;
    data(int a=0,int b=0){
        val=a,tim=b;
    }
}sta[MAXN];

int a[MAXN],pos[MAXN];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    a[n+1]=INF;
    for(int i=n+1;i>=1;i--){
        data tem(a[i],i);
        while(top&&sta[top].val<tem.val){
            top--;
        }
        pos[i]=sta[top].tim;
        sta[++top]=tem;
    }
    long long ans=0;
    for(int i=1;i<=n;i++)ans+=pos[i]-i-1;
    printf("%lld\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值