Submission #1369441

#TimeUsernameProblemLanguageResultExecution timeMemory
1369441solution6312Legendary Dango Eater (JOI26_dango)C++17
23 / 100
2595 ms148792 KiB
#include <iostream>
#include <cassert>
#include <set>
using namespace std;
using ll=long long;
using pli=pair<ll, int>;

const int MN=5e5+13, ML=22;
const int inf32=1e9;
int N, Q; ll K;
ll A[MN], pre[MN], rem[MN];
int nxt[MN][ML]; ll wgt[MN][ML];

int main()
{
    cin>>N>>Q>>K;
    for (int i=1; i<=N; i++)
    {
        cin>>A[i];
        if (i&1) pre[i]=pre[i-1]+A[i];
        else pre[i]=pre[i-1]-A[i];
        rem[i]=(pre[i]%K+K)%K;
    }
    set<pli> st;
    for (int y=1; y<=N; y+=2)
    {
        for (auto [rem, x]:st) assert(pre[x-1]<=pre[y]);
        st.insert({rem[y-1], y});
        if (rem[y]-A[y+1]+1<=rem[y])
        {
            auto it=st.lower_bound({rem[y]-A[y+1]+1, 0});
            while (it!=st.end() && it->first<=rem[y])
            {
                nxt[it->second][0]=y;
                //cerr<<it->second<<" TO "<<y<<endl;
                st.erase(it);
                it=st.lower_bound({rem[y]-A[y+1]+1, 0});
            }
        }
        auto it=st.lower_bound({max(rem[y]+1, rem[y]-A[y+1]+K+1), 0});
        while (it!=st.end())
        {
            nxt[it->second][0]=y;
            //cerr<<it->second<<" TO "<<y<<endl;
            st.erase(it);
            it=st.lower_bound({max(rem[y]+1, rem[y]-A[y+1]+K+1), 0});
        }
        if (y+2>N)
        {
            for (auto [rem, x]:st)
            {
                nxt[x][0]=y;
                //cerr<<x<<" TO "<<y<<endl;
            }
        }
    }
    for (int x=1; x<=N; x+=2)
    {
        assert(nxt[x][0]);
        wgt[x][0]=(pre[nxt[x][0]]-pre[x-1])/K;
    }
    for (int j=1; j<ML; j++)
    {
        for (int i=1; i<=N; i++)
        {
            if (nxt[i][j-1]+2>N) nxt[i][j]=inf32;
            else
            {
                nxt[i][j]=nxt[nxt[i][j-1]+2][j-1];
                wgt[i][j]=wgt[i][j-1]+wgt[nxt[i][j-1]+2][j-1];
            }
        }
    }
    while (Q--)
    {
        int L, R; cin>>L>>R;
        if (!(L&1)) L++;
        if (!(R&1)) R--;
        if (L>R)
        {
            cout<<0<<endl;
            continue;
        }
        ll ans=0;
        for (int i=ML-1; i>=0; i--)
        {
            //cerr<<L<<' '<<i<<": "<<nxt[L][i]<<' '<<wgt[L][i]<<endl;
            assert(L&1);
            if (L<=N && nxt[L][i]<=R)
            {
                ans+=wgt[L][i];
                L=nxt[L][i]+2;
            }
        }
        if (L<=R) ans+=(pre[R]-pre[L-1])/K;
        cout<<ans<<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...