제출 #945304

#제출 시각아이디문제언어결과실행 시간메모리
945304vjudge1Sum Zero (RMI20_sumzero)C++14
100 / 100
248 ms20340 KiB
#include <bits/stdc++.h>
using namespace std;

namespace std {

template <int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
    static_assert(D >= 1, "Dimension must be positive");
    template <typename... Args>
    Vec(int n = 0, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {}
};

template <typename T>
struct Vec<1, T> : public vector<T> {
    Vec(int n = 0, T val = T()) : std::vector<T>(n, val) {}
};

/* Example
    Vec<4, int64_t> f(n, k, 2, 2); // = f[n][k][2][2];
    Vec<2, int> adj(n); // graph
*/

template <class Fun>
class y_combinator_result {
    Fun fun_;

   public:
    template <class T>
    explicit y_combinator_result(T &&fun) : fun_(std::forward<T>(fun)) {}

    template <class... Args>
    decltype(auto) operator()(Args &&...args) {
        return fun_(std::ref(*this), std::forward<Args>(args)...);
    }
};

template <class Fun>
decltype(auto) y_combinator(Fun &&fun) {
    return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
}

/* Example
    auto fun = y_combinator([&](auto self, int x) -> void {
        self(x + 1);
    });
*/

}  // namespace std
const int N = 400002;
int a[N], jump[N], prv[N], depth[N], b[N + 1];
int64_t pref[N + 1];
int64_t sum = 0;
int n, l, r, res, q, k;

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 2; i <= n + 1; i++) cin >> a[i];
    for (int i = 2; i <= n + 1; i++) pref[i + 1] = pref[i] + a[i];
    sort(pref + 2, pref + n + 3);
    k = unique(pref + 2, pref + n + 3) - pref - 2;
    memset(b, -1, sizeof b);
    b[lower_bound(pref + 2, pref + k + 2, 0) - pref + 2] = 1;
    prv[0] = 0;
    prv[1] = 0;
    depth[0] = 0;
    depth[1] = 1;
    jump[1] = 0;

    for (int i = 2; i <= n + 1; i++) {
        sum += a[i];
        l = lower_bound(pref + 2, pref + 2 + k, sum) - pref + 2;
        if (b[l] != -1) {
            prv[i] = b[l];
            prv[i] = max(prv[i], prv[i - 1]);
        } else {
            prv[i] = prv[i - 1];
        }
        depth[i] = depth[prv[i]] + 1;
        if (depth[prv[i]] - depth[jump[prv[i]]] == depth[jump[prv[i]]] - depth[jump[jump[prv[i]]]]) {
            jump[i] = jump[jump[prv[i]]];
        } else {
            jump[i] = prv[i];
        }
        b[l] = i;
    }

    cin >> q;
    while (q--) {
        cin >> l >> r;
        res = 0;
        r++;
        while (r >= l) {
            if (jump[r] >= l) {
                res += depth[r] - depth[jump[r]];
                r = jump[r];
            } else if (prv[r] >= l) {
                res++;
                r = prv[r];
            } else {
                break;
            }
        }
        cout << res << '\n';
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...