Submission #1181612

#TimeUsernameProblemLanguageResultExecution timeMemory
118161212345678Escape Route 2 (JOI24_escape2)C++20
90 / 100
3103 ms350228 KiB
#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int nx=1e5+5, kx=17, th=250;

struct sparsesegtree
{
    struct node
    {
        pair<ll, ll> mn;
        node *l, *r;
        node(pair<ll, ll> vl=make_pair(1e18, 0)): mn(vl), l(0), r(0){}
    };
    typedef node* pnode;
    pnode rt[nx];
    void update(int l, int r, pnode &k, int idx, pair<ll, ll> vl)
    {
        if (!k) k=new node();
        if (idx<l||r<idx) return;
        if (l==r) return k->mn=min(k->mn, vl), void();
        int md=(l+r)/2;
        update(l, md, k->l, idx, vl);
        update(md+1 ,r, k->r, idx, vl);
        k->mn=min(k->l->mn, k->r->mn);
    }
    pair<ll, ll> query(int l, int r, pnode k, int ql, int qr)
    {
        if (qr<l||r<ql||!k||qr<ql) return {1e18, 0};
        if (ql<=l&&r<=qr) return k->mn;
        int md=(l+r)/2;
        return min(query(l, md ,k->l, ql, qr), query(md+1, r, k->r, ql, qr));
    }
} s;

ll n, t, m[nx], q, l, r, res, cur, loc, row;
vector<vector<ll>> pa[nx], cst[nx];
vector<ll> a[nx], b[nx], ans[nx], dp[nx];

int main()
{
    cin.tie(NULL)->sync_with_stdio(false);
    cin>>n>>t;
    for (int i=1; i<n; i++)
    {
        cin>>m[i];
        pa[i].resize(m[i]);
        cst[i].resize(m[i]);
        a[i].resize(m[i]);
        b[i].resize(m[i]);
        dp[i].resize(m[i]);
        for (int j=0; j<m[i]; j++) cin>>a[i][j]>>b[i][j], pa[i][j].resize(kx), cst[i][j].resize(kx);
    }
    for (int i=1; i<n-1; i++)
    {
        for (int j=0; j<m[i+1]; j++) s.update(0, t-1, s.rt[i+1], a[i+1][j], {b[i+1][j], j});
        for (int j=0; j<m[i]; j++)
        {
            //cout<<"before "<<i<<' '<<j<<'\n';
            auto x=s.query(0, t-1, s.rt[i+1], b[i][j], t-1);
            x.first+=(-b[i][j]);
            auto y=s.query(0, t-1, s.rt[i+1], 0, b[i][j]-1);
            y.first+=(t-b[i][j]);
            pair<ll, ll> mn=min(x, y);
            pa[i][j][0]=mn.second;
            cst[i][j][0]=mn.first;
            //cout<<"debug "<<i<<' '<<j<<' '<<pa[i][j][0]<<'\n';
        }
    }
    for (int k=1; k<kx; k++)
    {
        for (int i=1; i<n; i++)
        {
            if (i+(1<<k)>n-1) continue;
            for (int j=0; j<m[i]; j++) 
            {
                pa[i][j][k]=pa[i+(1<<(k-1))][pa[i][j][k-1]][k-1];
                cst[i][j][k]=cst[i][j][k-1]+cst[i+(1<<(k-1))][pa[i][j][k-1]][k-1];
            }
        }
    }
    for (int i=1; i<n; i++)
    {
        if (m[i]>=th)
        {
            ans[i].resize(n, 1e18);
            for (int j=0; j<m[i]; j++) dp[i][j]=b[i][j]-a[i][j];
            for (int j=i; j<n; j++)
            {
                for (int k=0; k<m[j]; k++) ans[i][j]=min(ans[i][j], dp[j][k]);
                if (j<n-1)
                {
                    for (int k=0; k<m[j+1]; k++) dp[j+1][k]=1e18;
                    for (int k=0; k<m[j]; k++) dp[j+1][pa[j][k][0]]=min(dp[j+1][pa[j][k][0]], dp[j][k]+cst[j][k][0]);
                }
            }
        }
    }
    cin>>q;
    while (q--)
    {
        cin>>l>>r;
        if (m[l]>=th)
        {
            cout<<ans[l][r-1]<<'\n';
        }
        else
        {
            res=LLONG_MAX;
            for (int i=0; i<m[l]; i++)
            {
                loc=l, row=i;
                cur=b[l][i]-a[l][i];
                for (int j=kx-1; j>=0; j--) if (loc+(1<<j)<r) cur+=cst[loc][row][j], row=pa[loc][row][j], loc+=(1<<j);
                res=min(res, cur);
            }
            cout<<res<<'\n';
        }
    }
}
#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...