QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#569011 | #9313. Make Max | zy_sy | RE | 0ms | 0kb | C++20 | 2.7kb | 2024-09-16 19:53:36 | 2024-09-16 19:53:36 |
Judging History
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;
}
详细
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