제출 #1365030

#제출 시각아이디문제언어결과실행 시간메모리
1365030gelastropodLegendary Dango Eater (JOI26_dango)C++20
100 / 100
913 ms173020 KiB
#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long

set<pair<int, int>> ss;

void upd(int a, int b, int x) {
    auto iter1 = ss.lower_bound({ a, 0 });
    auto iter2 = ss.upper_bound({ b, 1e15 });
    auto iter3 = ss.upper_bound({ b + 1, 1e15 });
    iter3--;
    int guy = iter3->second;
    ss.erase(iter1, iter2);
    ss.insert({ a, x });
    ss.insert({ b + 1, guy });
}

int qry(int a) {
    auto iter = ss.upper_bound({ a, 1e15 });
    iter--;
    return iter->second;
}

signed main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int N, Q, K, a, b, crnt = 0; cin >> N >> Q >> K;
    vector<int> p = { 0 }, A;
    for (int i = 0; i < N; i++) {
        cin >> a;
        if (i % 2) {
            crnt -= a;
            A.push_back(-a);
        }
        else {
            crnt += a;
            A.push_back(a);
        }
        p.push_back(crnt);
    }
    if (N % 2) {
        N++;
        A.push_back(-1e15);
        p.push_back(crnt - 1e15);
    }
    ss.insert({ 0, N });
    vector<vector<pair<int, int>>> kpa(20, vector<pair<int, int>>(N + 1, {N + 1, -1}));
    for (int i = N - 1; i >= 0; i--) {
        if (i % 2) {
            if (A[i] <= -K) upd(0, K - 1, i);
            else {
                a = ((p[i] + A[i]) % K + K) % K, b = (p[i] % K + K) % K;
                if (a <= b) upd(a, b, i);
                else {
                    upd(0, b, i);
                    upd(a, K - 1, i);
                }
            }
        }
        int res = qry((p[i] % K + K) % K);
        kpa[0][i] = { res + 1, (p[res] - p[i]) / K };
    }
    for (int i = 1; i < 20; i++) {
        for (int j = 0; j <= N; j++) {
            if (kpa[i - 1][j].first == N + 1) continue;
            kpa[i][j] = kpa[i - 1][kpa[i - 1][j].first];
            kpa[i][j].second += kpa[i - 1][j].second;
        }
    }
    for (int i = 0; i < Q; i++) {
        cin >> a >> b; a--;
        int res = 0;
        for (int j = 19; j >= 0; j--) {
            if (kpa[j][a].first > b) continue;
            res += kpa[j][a].second;
            a = kpa[j][a].first;
        }
        res += (p[b] - p[a]) / K;
        cout << res << '\n';
    }
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…