51Nod 1349

来源:互联网 发布:java公钥加密私钥解密 编辑:程序博客网 时间:2024/06/06 11:02

继续学习单调栈! 利用单调栈求出数列中的每个数作为最大值的区间长度。

#include<stdio.h>#include<cstring>using namespace std;const int maxn = 100005;typedef long long ll;int num[maxn];int sta[maxn];ll l[maxn],r[maxn];ll ans[maxn];//inline int in()//{//    char ch;//    int a = 0;//    while((ch = getchar()) == ' ' || ch == '\n');//    a += ch - '0';//    while((ch = getchar()) != ' ' && ch != '\n')//    {//        a *= 10;//        a += ch - '0';//    }//    return a;//}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&num[i]);    ll top = 0;    for(int i=1;i<=n;i++)    {        while(top&&num[sta[top-1]]<=num[i]) top--;        if(!top) l[i] = 1;        else l[i] = sta[top-1] + 1;        sta[top++] = i;    }    top = 0;    for(int i=n;i>=1;i--)    {        while(top&&num[sta[top-1]]<num[i]) top--;        if(!top) r[i] = n;        else r[i] = sta[top-1] - 1;        sta[top++] = i;    }    memset(ans,0,sizeof(ans));    for(ll i=1;i<=n;i++)        ans[num[i]] += (i-l[i]+1)*(r[i]-i+1);    for(int i=100000;i>=1;i--)        ans[i] += ans[i+1];    int q,a; scanf("%d",&q);    while(q--)    {        scanf("%d",&a);        printf("%I64d\n",ans[a]);    }    return 0;}


原创粉丝点击