Submission #1369026

#TimeUsernameProblemLanguageResultExecution timeMemory
1369026pcheloveksLegendary Dango Eater (JOI26_dango)C++20
27 / 100
483 ms224536 KiB
#define _CRT_SECURE_NO_WARNINGS
 
#include <bits/stdc++.h>
 
#define endl '\n'
 
#pragma GCC optimize("Ofast")
 
using namespace std;
 
using ll = long long;
using ld = long double;
using pii = pair < int, int >;
using pll = pair < ll, ll >;
 
const ll INF = 2e18;
const ll DIM = 500007;
const ld PI = 3.1415926535;
const int mod = 998244353;

class segTreeMi {
public:

    void build(int sz) {
        this->sz = sz;
        T.resize(4 * sz + 7, INF);
    }

    void update(ll pos, ll val) {
        update(0, 1, sz, pos, val);
    }

    ll query(ll x) {
        return query(0, 1, sz, x);
    }

private:

    void update(int val, int tl, int tr, int pos, ll x) {
        if(tl == tr) {
            T[val] = x;
            return;
        }

        int tm = (tl + tr) >> 1;
        if(pos <= tm) {
            update(2 * val + 1, tl, tm, pos, x);
        }
        else {
            update(2 * val + 2, tm + 1, tr, pos, x);
        }
        T[val] = min(T[2 * val + 1], T[2 * val + 2]);
    } 

    ll query(int val, int tl, int tr, ll x) {
        if(tl == tr) {
            if(T[val] <= x) return tl;
            return INF;
        }

        int tm = (tl + tr) >> 1;
        if(T[2 * val + 1] <= x) return query(2 * val + 1, tl, tm, x);
        else return query(2 * val + 2, tm + 1, tr, x);
    }

    int sz;
    vector < ll > T;
};

class segTreeMx {
public:

    void build(int sz) {
        this->sz = sz;
        T.resize(4 * sz + 7, -INF);
    }

    void update(ll pos, ll val) {
        update(0, 1, sz, pos, val);
    }

    ll query(ll x) {
        return query(0, 1, sz, x);
    }

private:

    void update(int val, int tl, int tr, int pos, ll x) {
        if(tl == tr) {
            T[val] = x;
            return;
        }

        int tm = (tl + tr) >> 1;
        if(pos <= tm) {
            update(2 * val + 1, tl, tm, pos, x);
        }
        else {
            update(2 * val + 2, tm + 1, tr, pos, x);
        }
        T[val] = max(T[2 * val + 1], T[2 * val + 2]);
    } 

    ll query(int val, int tl, int tr, ll x) {
        if(tl == tr) {
            if(T[val] >= x) return tl;
            return INF;
        }

        int tm = (tl + tr) >> 1;
        if(T[2 * val + 1] >= x) return query(2 * val + 1, tl, tm, x);
        else return query(2 * val + 2, tm + 1, tr, x);
    }

    int sz;
    vector < ll > T;
};

struct jump {
    int toP, toX;
    ll val;
};

vector < vector < vector < jump > > > j;

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
#ifdef IloveCP
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ll n, q, k;
    cin >> n >> q >> k;

    vector < ll > a(n + 1);
    for(int i = 1; i <= n; i++) cin >> a[i];

    vector < ll > p(n + 1, 0);
    for(int i = 1; i <= n; i++) {
        if(i % 2 == 1) p[i] = a[i];
        else p[i] = -a[i];

        p[i] += p[i - 1];
    }

    j.resize(n + 1);

    int firstZero = n + 1;

    segTreeMi tmi;
    segTreeMx tmx;
    tmi.build(n);
    tmx.build(n);

    for(int i = n; i >= 1; i--) {
        if(i % 2 == 1) {
            j[i].resize(a[i] + 1, vector < jump >(19));
            for(int x = 0; x <= a[i]; x++) {
                ll tmp = x;

                j[i][x][0].val = tmp / k;
                tmp %= k;

                ll pos = min(tmi.query(p[i] - tmp - 1), tmx.query(k + p[i] - tmp));

                if(pos == INF) {
                    j[i][x][0].toP = n + 1;
                    j[i][x][0].toX = 0;
                }
                else if(pos % 2 == 1) {
                    j[i][x][0].toP = pos;

                    j[i][x][0].toX = p[pos] - p[i] + tmp - k;
                    j[i][x][0].val++;
                }
                else if(pos % 2 == 0) {
                    if(pos == n) {
                        j[i][x][0].toP = n + 1;
                        j[i][x][0].toX = 0;
                    }
                    else {
                        j[i][x][0].toP = pos + 1;
                        j[i][x][0].toX = a[pos + 1];
                    }
                }

                /*
                cout << i << " " << x << "          ";
                cout << j[i][x][0].toX << " ";
                cout << j[i][x][0].toP << " ";
                cout << j[i][x][0].val << endl;
                */

                for(int p = 1; p < 19; p++) {
                    if(j[i][x][p - 1].toP <= n) {
                        j[i][x][p].val = j[i][x][p - 1].val + j[j[i][x][p - 1].toP][j[i][x][p - 1].toX][p - 1].val;
                        j[i][x][p].toP = j[j[i][x][p - 1].toP][j[i][x][p - 1].toX][p - 1].toP;
                        j[i][x][p].toX = j[j[i][x][p - 1].toP][j[i][x][p - 1].toX][p - 1].toX;
                    }
                    else j[i][x][p] = j[i][x][p - 1];
                }
            }
        }

        tmi.update(i, p[i]);
        tmx.update(i, p[i]);
    }

    for(int i = 0; i < q; i++) {
        ll l, r;
        cin >> l >> r;
        if(l % 2 == 0) l++; 
        if(r % 2 == 0) r--;
        
        if(l > r) {
            cout << 0 << endl;
            continue;
        }

        ll curr = l;
        ll res = 0;
        ll x = a[l];

        for(int p = 18; p >= 0; p--) {
            if(j[curr][x][p].toP <= r) {
                res += j[curr][x][p].val;
                ll tox = j[curr][x][p].toX;
                ll top = j[curr][x][p].toP;

                x = tox; curr = top;
            }
        }
        res += x / k;

        cout << res << endl;
    }


    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...