Submission #1341106

#TimeUsernameProblemLanguageResultExecution timeMemory
1341106alexddFish 3 (JOI24_fish3)C++20
100 / 100
437 ms59832 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e18;

int n,d;
int c[300005];
int prefr[300005];
int rez[300005], qle[300005], qri[300005];
vector<int> qrys_ofri[300005];
int val[300005], pref_val[300005];


struct node
{
    int minv = INF, sum = 0;
};
node combine(node x, node y)
{
    node aux;
    aux.minv = min(x.minv, y.minv);
    aux.sum = x.sum + y.sum;
    return aux;
}
node aint[1100000];
int lazy[1100000];
void build(int nod, int st, int dr)
{
    lazy[nod] = INF;
    aint[nod] = {};
    if(st == dr)
        return;
    int mij = (st + dr) / 2;
    build(nod*2,st,mij);
    build(nod*2+1,mij+1,dr);
}
void handle(int nod, int newv, int st, int dr)
{
    aint[nod].minv = newv;
    aint[nod].sum = newv * (dr - st + 1);
    lazy[nod] = newv;
}
void propagate(int nod, int st, int dr)
{
    if(lazy[nod] == INF)
        return;
    int mij = (st + dr) / 2;
    handle(nod*2, lazy[nod], st, mij);
    handle(nod*2+1, lazy[nod], mij+1, dr);
    lazy[nod] = INF;
}
void upd(int nod, int st, int dr, int le, int ri, int newv)
{
    if(le > ri)
        return;
    if(le == st && dr == ri)
    {
        handle(nod, newv, st, dr);
        return;
    }
    propagate(nod, st, dr);
    int mij = (st + dr) / 2;
    upd(nod*2,st,mij,le,min(mij,ri),newv);
    upd(nod*2+1,mij+1,dr,max(mij+1,le),ri,newv);
    aint[nod] = combine(aint[nod*2], aint[nod*2+1]);
}
node qry(int nod, int st, int dr, int le, int ri)
{
    if(le > ri)
        return {};
    if(le == st && dr == ri)
        return aint[nod];
    propagate(nod,st,dr);
    int mij = (st + dr) / 2;
    return combine(qry(nod*2,st,mij,le,min(mij,ri)), qry(nod*2+1,mij+1,dr,max(mij+1,le),ri));
}

signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n>>d;
    for(int i=1;i<=n;i++)
    {
        cin>>c[i];
        prefr[i] = prefr[i-1] + ((c[i] - c[i-1]) % d + d) % d;
        val[i] = c[i] - prefr[i];
        pref_val[i] = pref_val[i-1] + val[i];
    }
    int q;
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        cin>>qle[i]>>qri[i];
        qrys_ofri[qri[i]].push_back(i);
    }


    vector<int> st;
    val[0] = -INF;
    st.push_back(0);
    build(1,1,n);
    for(int ri=1;ri<=n;ri++)
    {
        while(val[ri] < val[st.back()])
            st.pop_back();
        upd(1,1,n, st.back() + 1, ri, val[ri]);
        st.push_back(ri);

        for(int qid:qrys_ofri[ri])
        {
            int le = qle[qid];
            int dif = prefr[le] - c[le] % d;
            node aux = qry(1,1,n,le,ri);
            int mnm = aux.minv, sum = aux.sum;

            if(mnm + dif < 0)
            {
                rez[qid] = -1;
                continue;
            }

            int tot = pref_val[ri] - pref_val[le-1];
            assert((tot - sum) % d == 0);
            rez[qid] = (tot - sum) / d;
        }
    }
    for(int i=1;i<=q;i++)
        cout<<rez[i]<<"\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...