NowCoder--牛可乐发红包脱单ACM赛C_区区区间间间
Posted dyloder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NowCoder--牛可乐发红包脱单ACM赛C_区区区间间间相关的知识,希望对你有一定的参考价值。
题目链接: C_区区区间间间
思路:算贡献,求出每个数为当前最大值时所在的区间个数,和每个数为最小值的区间个数
和这个题有点类似 搭配食用效果更佳 点击这里
#include<bits/stdc++.h> using namespace std; #define maxn 100005 #define LL long long LL ll[maxn],rr[maxn],a[maxn]; LL work(LL n){ memset(ll,0,sizeof(ll)); memset(rr,0,sizeof(rr)); stack<int>s,t; for(LL j=1;j<=n;j++){ while(s.size()&&a[j]>=a[s.top()]){ s.pop(); } if(!s.size()) ll[j]=1; else ll[j]=s.top()+1; s.push(j); } for(LL j=n;j>=1;j--){ while(t.size()&&a[j]>a[t.top()]){ t.pop(); } if(!t.size()) rr[j]=n; else rr[j]=t.top()-1; t.push(j); } LL ans=0; for(LL j=1;j<=n;j++){ ans+=1LL*a[j]*1LL*(rr[j]-ll[j]+(rr[j]-j)*(j-ll[j])); } return ans; } int main(){ LL t; cin>>t; while(t--){ LL n; cin>>n; for(LL j=1;j<=n;j++){ scanf("%d",&a[j]); } LL ans=work(n); //cout<<ans<<endl; for(LL j=1;j<=n;j++){ // 赋值的时候相当于找最大 得到的结果就是负数 正好减去 a[j]=-a[j]; } ans+=work(n); cout<<ans<<endl; } }
以上是关于NowCoder--牛可乐发红包脱单ACM赛C_区区区间间间的主要内容,如果未能解决你的问题,请参考以下文章