「CSP-S 2020」贪吃蛇 - 题目 - Liuser's OJ
样例
样例输入 1
复制2
3
11 14 14
3
1 5 2 6 3 25
样例输出 1
复制3
1
样例输入 2
复制2
5
13 31 33 39 42
5
1 7 2 10 3 24 4 48 5 50
样例输出 2
复制5
3
因为有文件,请其他人提交时注释掉freopen
核心代码:
const int N = 1000005, INF = 2e9;
int n, a[N], d[N], mx[N], mn[N], ans;
struct E{
int x, id;
bool operator < (const E &b) const {
if (x != b.x) return x < b.x;
return id < b.id;
}
bool operator == (const E &b) const {
return x == b.x && id == b.id;
}
};
E b[N], c[N], f[N];
int hh, tt, L, R;
E inline getMax() {
E x = (E) { -1, -1 };
if (hh <= tt && x < b[hh]) x = b[hh];
if (L <= R && x < c[L]) x = c[L];
if (hh <= tt && x == b[hh]) hh++;
if (L <= R && x == c[L]) L++;
return x;
}
E inline getMin() {
E x = (E) { INF, INF };
if (hh <= tt && b[tt] < x) x = b[tt];
if (L <= R && c[R] < x) x = c[R];
if (hh <= tt && x == b[tt]) tt--;
if (L <= R && x == c[R]) R--;
return x;
}
void inline merge() {
int len = tt - hh + 1 + R - L + 1;
for (int k = 1, i = hh, j = L; k <= len; k++) {
if (j > R || (i <= tt && c[j] < b[i])) f[k] = b[i++];
else f[k] = c[j++];
}
L = 0, R = -1;
hh = 1, tt = len;
for (int i = 1; i <= len; i++) b[i] = f[i];
}
void inline solve() {
hh = 0, tt = -1, L = 0, R = -1;
memset(d, 0, sizeof d);
ans = 1;
for (int i = n; i; i--) b[++tt] = (E) { a[i], i };
bool ok = false;
for (int i = n; i >= 2; i--) {
E A = getMax(), B = getMin();
mx[i] = A.id, mn[i] = B.id;
c[++R] = (E) { A.x - B.x, mx[i] };
if (!ok && A.x < B.x * 2) {
ok = true;
merge();
}
d[mn[i]] = i - 1;
}
for (int i = 2; i <= n; i++)
if (d[mx[i]] >= ans) ans = i;
printf("%d\n", ans);
}