题目链接: 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()]){ // 一个等号一个大于号 比如 666 的情况 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;} }