单调栈:

https://www.starrycoding.com/problem/60
暴力:(包超时的,剪枝也超时)
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
int res[N];
void solve() {
a[0] = 1e9 + 1;
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] < a[i - 1] && res[i - 1] == -1) {
res[i] = -1;
}
for (int j = i - 1; j >= 0; j--) {
if (a[j] < a[i]) {
res[i] = a[j];
j = -1;
}
}
if (!res[i]) {
res[i] = -1;
}
}
for (int i = 1; i <= n; i++) {
cout << res[i] << " ";
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
单调栈:(STL写法)
栈存值
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
int res[N];
stack<int> sta;
void solve() {
int n;
cin >> n;
sta.push(1e9 + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
while (!sta.empty() && sta.top() >= a[i]) sta.pop();
if (sta.empty()) {
res[i] = -1;
} else
res[i] = sta.top();
sta.push(a[i]);
}
for (int i = 1; i <= n; i++) {
cout << res[i] << " ";
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
单调栈:(数组模拟,改改就完事了,不用加逻辑)
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
int res[N];
int sta[N], top;
void solve() {
int n;
cin >> n;
sta[++top] = 1e9 + 1;
for (int i = 1; i <= n; i++) {
cin >> a[i];
while (top && sta[top] >= a[i]) top--;
if (!top) {
res[i] = -1;
} else
res[i] = sta[top];
sta[++top] = a[i];
}
for (int i = 1; i <= n; i++) {
cout << res[i] << " ";
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
单调队列:
https://www.starrycoding.com/problem/61
栈存下标
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int a[N], res_min[N], res_max[N];
void solve() {
int n, k;
cin >> n >> k;
deque<int> deq; //存储下标
for (int i = 1; i <= n; i++) cin >> a[i];
// max
for (int i = 1; i <= n; i++) {
//验证队头合理性,大小是否合理
while (deq.size() && deq.front() <= i - k) deq.pop_front();
//验证队尾优越性,选大的
while (deq.size() && a[deq.back()] <= a[i]) deq.pop_back();
deq.push_back(i);
if (i >= k) cout << a[deq.front()] << " "; //一定是头最大
}
fuck = deque<int>(); //清空
cout << endl;
// min
for (int i = 1; i <= n; i++) {
//验证队头合理性,大小是否合理
while (deq.size() && deq.front() <= i - k) deq.pop_front();
//验证队尾优越性,选小的
while (deq.size() && a[deq.back()] >= a[i]) deq.pop_back();
deq.push_back(i);
if (i >= k) cout << a[deq.front()] << " "; //一定是头最小
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
模拟队列:(数组模拟,改改就完事了,不用加逻辑)
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int a[N], res_min[N], res_max[N];
int fuck[N], front, back;
void solve() {
int n, k;
cin >> n >> k;
// deque<int> fuck; //存储下标
for (int i = 1; i <= n; i++) cin >> a[i];
// max
for (int i = 1; i <= n; i++) {
//验证队头合理性,大小是否合理
while (back - front + 1 && fuck[front] <= i - k) front++;
//验证队尾优越性,选大的
while (back - front + 1 && a[fuck[back]] <= a[i]) back--;
fuck[++back] = i;
if (i >= k) cout << a[fuck[front]] << " "; //一定是头最大
}
front = 1;
back = 0; //清空
cout << endl;
// min
for (int i = 1; i <= n; i++) {
//验证队头合理性,大小是否合理
while (back - front + 1 && fuck[front] <= i - k) front++;
//验证队尾优越性,选小的
while (back - front + 1 && a[fuck[back]] >= a[i]) back--;
fuck[++back] = i;
if (i >= k) cout << a[fuck[front]] << " "; //一定是头最小
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
/https://www.starrycoding.com/problem/62
栈存下标
// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 1e5 + 9;
int sta[N], top;
int a[N], l[N], r[N];
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) { //左闭
while (top && a[sta[top]] >= a[i]) top--; //找最小
if (!top) //均比a[i]大
l[i] = 0;
else //存在比a[i]小
l[i] = sta[top];
sta[++top] = i; //压入
}
top = 0; //清空
for (int i = n; i >= 1; i--) { //右开
while (top && a[sta[top]] > a[i]) top--; //找最小
if (!top) //均比a[i]大
r[i] = n + 1;
else //存在比a[i]小
r[i] = sta[top];
sta[++top] = i; //压入
}
int res = 0;
for (int i = 1; i <= n; i++) {
res += a[i] * (r[i] - i) * (i - l[i]); // a[i]乘两边元素个数的乘积求和
}
cout << res;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}