QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#569011#9313. Make Maxzy_syRE 0ms0kbC++202.7kb2024-09-16 19:53:362024-09-16 19:53:36

Judging History

你现在查看的是最新测评结果

  • [2024-09-18 15:56:24]
  • hack成功,自动添加数据
  • (/hack/836)
  • [2024-09-16 19:53:36]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-09-16 19:53:36]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, nums[N], Left[N], Right[N];
stack<int> s;

//快速读取算法
inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int main(){
    int T = read();
    while(T--){
        n = read();
        for(int i = 1;i<=n;i++){
            nums[i] = read();
        }
        //计算每个点右侧第一个大于等于该点的点的位置
        for(int i = 1;i<=n;i++){
            //栈内未储存地址时向内补充地址
            //当前数比栈内地址处的数小的时候,储存当前数地址
            if(s.empty()||nums[i]<nums[s.top()]){
                s.push(i);
            }else{
                //当当前数比栈内地址处数大时,记录地址,弹出栈内地址,知道当前数比栈内地址处数小或栈空时
                while(!s.empty()&&nums[i]>=nums[s.top()]){
                    Right[s.top()] = i;
                    s.pop();
                }
                //储存当前数地址
                s.push(i);
            }
        }
        //最大的数无法弹出,将比最大数大的数的地址记录为一个无意义的地址
        while(!s.empty()){
            Right[s.top()] = n+1;
            s.pop();
        }
        //重复上述过程储存左端地址
        for(int i = n;i;i--){
            //栈内未储存地址时向内补充地址
            //当前数比栈内地址处的数小的时候,储存当前数地址
            if(s.empty()||nums[i]<nums[s.top()]){
                s.push(i);
            }else{
                //当当前数比栈内地址处数大或相等时,记录地址,弹出栈内地址,直到当前数比栈内地址处数小或栈空时
                while(!s.empty()&&nums[i]>=nums[s.top()]){
                    Left[s.top()] = i;
                    s.pop();
                }
                //储存当前数地址
                s.push(i);
            }
        }
        //最大的数无法弹出,将比最大数大的数的地址记录为一个无意义的地址
        while(!s.empty()){
            Left[s.top()] = 0;
            s.pop();
        }
        long long ans = 0LL;
        //根据左右地址计算结果
        for(int i = 1;i<=n;i++){
            if(!Left[i]||nums[Left[i]]!=nums[i]){
                ans+=(Right[i]-Left[i]-2);
            }else{
                ans+=(Right[i]-i-1);
            }
        }
        printf("%lld\n", ans);
    }
    delete Right;
    delete Left;
    delete nums;
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Runtime Error

input:

4
2
1 2
2
2 2
7
1 1 1 2 2 2 2
3
1 2 3

output:


result: