「CSP-S 2020」贪吃蛇

「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); 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值