Submission #1359942

#TimeUsernameProblemLanguageResultExecution timeMemory
1359942BigBadBullyLegendary Dango Eater (JOI26_dango)C++20
100 / 100
842 ms224916 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
#define tri array<int, 3>
const int inf = 2e18;
const int mod = 1e9+7;
const int mxn = 2e6 + 1;
vector<int> fact(mxn+1,1),invfact(mxn+1,1);


int exp(int x, int n)
{
    int res = 1;
    for (; n > 0; res = (n % 2 ? res * x % mod : res), x = x * x % mod, n /= 2)
        ;
    return res;
}

int inv(int x)
{
    return exp(x, mod - 2);
}



void init()
{
    for(int i = 1; i <= mxn; i++)
        fact[i]=fact[i-1]*i%mod;
    invfact[mxn] = inv(fact[mxn]);
    for(int i = mxn-1; i >= 0; i--)
        invfact[i]=invfact[i+1]*(i+1)%mod;
    
}

int ncr(int n,int r)
{
    if(n<r ||n<0||r<0)
        return 0;
    return fact[n]*invfact[r]%mod*invfact[n-r]%mod;
}


struct seggy{
    int n;
    vector<int> t;
    seggy(int sz)
    {
        n = sz;
        t.resize(2*n,inf);
    }
    void update(int i,int x)
    {
        for(t[i+=n]=x;i>1;i/=2)
            t[i/2]=min(t[i],t[i^1]);
    }
    int query(int l,int r)
    {
        int res = inf;
        r++;
        for(l+=n,r+=n;l<r;l/=2,r/=2)
        {
            if(l&1)
                res=min(res,t[l++]);
            if(r&1)
                res = min(res,t[--r]);
        }
        return res; 
    }
};



void solve()
{
    int n,q,k;
    cin >> n >> q >> k;
    vector<int> v(n);
    for(int&x:v)cin>>x;
    v.push_back(0);v.push_back(0);
    vector<pii> nxt(n+2,{n,0});
    vector<int> pref(n+2,0),pmk(n+2,0);
    for(int i = 0;i < n; i++)
        v[i]*=(i%2?-1:1),pref[i]=(i>0?pref[i-1]:0)+v[i];
    vector<int> mdk = pref;
    for(int&x:mdk)
    {
        int modu = 1;
        while(modu*k<abs(x))
            modu*=2;
        x=(modu*k+x)%k;
    }
    function<int(int,int)> sum =[&](int l,int r)
    {
        if(l>r)return 0ll;
        return pref[r]-(l>0?pref[l-1]:0);
    };
    int run = 0;

    set<pii> mile;
    for(int i = 0; i <n; i++)
    {
        if(i%2==0)
            mile.insert({(i>0?(k-mdk[i-1])%k:0),i});
        else
        {
            while(mile.size()&&(*mile.begin()).ff < k-run)
            {
                pii cur = *mile.begin();
                if(abs(v[i])>=cur.ff+run)
                    nxt[cur.ss] = {i,max(0ll,sum(cur.ss,i-1)/k)};
                else
                    break;
                mile.erase(cur);
            }
            while(mile.size())
            {
                auto it = mile.lower_bound({k-run,-1});
                if(it!=mile.end())
                {
                    pii cur = *it;
                    if(abs(v[i])>=(cur.ff+run)%k)
                        nxt[cur.ss] = {i,max(0ll,sum(cur.ss,i-1)/k)};
                    else
                        break;
                    mile.erase(cur);
                }
                else break;
            }
            nxt[i]={i+1,0};
        }    
        run+=(int)(1e9)*k+v[i];
        run%=k;
    }
    for(pii cur:mile)
        nxt[cur.ss] = {n,max(0ll,sum(cur.ss,n-1)/k)};

    
    vector<vector<pii>> lift(20,vector<pii>(n+2,{n,0}));
    lift[0] = nxt;
    for(int b = 1;b < 20;b++)
        for(int i = 0; i < n; i++)
        {
            lift[b][i].ss = lift[b-1][i].ss+lift[b-1][lift[b-1][i].ff].ss;
            lift[b][i].ff = lift[b-1][lift[b-1][i].ff].ff;
        }
    while(q--)
    {
        int l,r;
        cin >> l>>r;
        --l,--r;
        int tot = 0;
        for(int b = 19;b>=0;b--)
            if(lift[b][l].ff<=r+1)
            {
                tot+=lift[b][l].ss;
                l=lift[b][l].ff;
            }
        cout<<tot+sum(l,r)/k<<'\n';
    }
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    init();

    int t=1;
    //cin >>t;
    while(t--)solve();
        
    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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...