SP9084 JRNTMRS - Journey to Mars 题解

SP9084

看到是一个环,先破环为链,即 $a_{n+i}=a_i, b_{n+i}=b_i$,此时就只需要跳到 $x+n$ 而无需判环了。

如果顺时针走:

令 $sum_i = \sum\limits_{j=1}^{i}{a_j-b_j}$,当能从 $x$ 跳到 $x+n$ 时,有

$$sum_{x-1} \le sum_x, sum_{x-1} \le sum_{x+1}, \dots, sum_{x-1} \le sum_{x+n-1}$$

变形一下:

$$sum_{x-1} \le \min\limits_{x \le i < x+n}\{sum_i\}$$

求长度不变区间的最小值,可以使用单调队列。

逆时针就反着再做一遍。

代码:

#include<bits/stdc++.h>

using ll = long long;
using pii = std::pair<int, int>;

const int N = 1e6 + 5;
int n, hd, tl; 
int a[N << 1], b[N << 1], c[N << 1], q[N << 1];
int ta[N], tb[N], ans[N], flag[N];
ll s[N << 1];

void solve() {
    for (int i = 1; i <= n; i++) s[i] = s[i - 1] + c[i];
    for (int i = 1; i <= n; i++) s[i + n] = s[i + n - 1] + c[i];
    for (int i = 1, hd = 1, tl = 0; i <= n * 2; i++) {
        if (hd <= tl && q[hd] < i - n + 1) hd++;
        while (hd <= tl && s[q[tl]] >= s[i]) tl--;
        q[++tl] = i;
        if (i >= n)
            ans[i - n + 1] = s[q[hd]];
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n;
    for (int i = 1; i <= n; i++) {
        std::cin >> a[i] >> b[i];
        a[i + n] = a[i], b[i + n] = b[i];
        c[i + n] = c[i] = a[i] - b[i];
    }
    solve();
    for (int i = 1; i <= n; i++)
        if (ans[i] >= s[i - 1])
            flag[i] = 1;
    for (int i = 1; i <= n; i++)
        c[i] = a[n - i + 1] - b[((n - i ? n - i : n))];
    solve();
    for (int i = 1; i <= n; i++)
        if (ans[i] >= s[i - 1])
            flag[n - i + 1] = 1;
    for (int i = 1; i <= n; i++)
        std::cout << (flag[i] ? "TAK" : "NIE") << "\n";
    return 0;
}

双倍经验

posted @ 2023-02-19 22:12  Pengzt  阅读(0)  评论(0编辑  收藏  举报  来源