Files
C_code/exercise/38.c
T

79 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 优化版:每个区间长度 k(1..n) 的最大区间价值 max(subarray_max * subarray_min)
// 算法:最大值笛卡尔树 + 跨越合并(单调两指针),整体显著优于 O(n^2)
// 说明:对每个树节点 i 及其覆盖段 [l,r],所有包含 i 的子数组最大值均为 a[i];
// 设从 i 向左取 x 个、向右取 y 个,长度 k=x+y+1,区间最小值为 min(Lmin[x], Rmin[y])
// 其中 Lmin/Rmin 为以 i 为中心的左/右最小值前后缀。对固定 s=x+y,
// 利用两指针在可行范围内最大化 min(Lmin[s-y], Rmin[y])O(lenL+lenR) 完成一次合并。
#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
static inline ll minll(ll a, ll b) { return a < b ? a : b; }
// 构建“以最大值为堆”的笛卡尔树。相等值用 <= 弹出以保证唯一性(倾向右侧作为父)。
// 输出:left child lcright child rcparent;返回根下标。
static int build_cartesian_tree(const ll *a, int n, int *lc, int *rc, int *parent) {
int *st = (int*)malloc((n + 1) * sizeof(int));
int top = 0;
int root = 0;
for (int i = 1; i <= n; ++i) {
int last = 0;
while (top > 0 && a[st[top - 1]] <= a[i]) {
last = st[--top];
}
if (top > 0) {
rc[st[top - 1]] = i;
parent[i] = st[top - 1];
} else {
root = i;
parent[i] = 0;
}
lc[i] = last;
if (last) parent[last] = i;
st[top++] = i;
}
free(st);
return root;
}
int main(void) {
int n;
if (scanf("%d", &n) != 1) return 0;
int cap = n + 5;
int *dq = (int*)malloc((size_t)cap * sizeof(int));
int head = 0, tail = 0, size = 0;
char *out = (char*)malloc((size_t)(n * 14 + 1));
int pos = 0;
for (int i = 0; i < n; ++i) {
int op;
scanf("%d", &op);
if (op == 1) {
int x; scanf("%d", &x);
head = (head - 1 + cap) % cap;
dq[head] = x;
++size;
} else if (op == 2) {
int x; scanf("%d", &x);
dq[tail] = x;
tail = (tail + 1) % cap;
++size;
} else if (op == 3) {
pos += sprintf(out + pos, "%d\n", dq[head]);
} else if (op == 4) {
int idx = (tail - 1 + cap) % cap;
pos += sprintf(out + pos, "%d\n", dq[idx]);
} else if (op == 5) {
head = (head + 1) % cap;
--size;
} else if (op == 6) {
tail = (tail - 1 + cap) % cap;
--size;
}
}
fwrite(out, 1, (size_t)pos, stdout);
free(out);
free(dq);
return 0;
}