Submission #1095149

#TimeUsernameProblemLanguageResultExecution timeMemory
1095149SalihSahinTrains (BOI24_trains)C++14
100 / 100
1036 ms9340 KiB
#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;

const int N = 3e5 + 5;
const int K = 20;
const int mod = 1e9 + 7;

struct SEGT{
    vector<int> tree;

    void init(int n){
        tree.assign(4*n, 0);
    }

    void update(int ind, int l, int r, int pos, int val){
        if(l == r){
            tree[ind] = (tree[ind] + val + mod)%mod;
        }
        else{
            int m = (l + r)/2;

            if(pos <= m) update(ind*2, l, m, pos, val);
            else update(ind*2+1, m+1, r, pos, val);

            tree[ind] = (tree[ind*2] + tree[ind*2+1])%mod;
        }
    }

    int query(int ind, int l, int r, int ql, int qr){
        if(l > r || l > qr || r < ql) return 0;
        if(l >= ql && r <= qr) return tree[ind];
        else{
            int m = (l + r)/2;
            return (query(ind*2, l, m, ql, qr) + query(ind*2+1, m+1, r, ql, qr))%mod;
        }
    }
};

int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int L = 200;
    vector<SEGT> seg(L + 5);
    for(int i = 1; i <= L; i++){
        seg[i].init(i);
    }

    int n;
    cin>>n;
    vector<array<int, 3> > updlist[n+5];
    vector<int> d(n+1), x(n+1), dp(n+1);
    for(int i = 1; i <= n; i++){
        cin>>d[i]>>x[i];
    }
    dp[1] = 1;
    int ans = 0;
    for(int i = 1; i <= n; i++){
        for(auto itr: updlist[i]){
            seg[itr[0]].update(1, 1, itr[0], itr[1], itr[2]);
        }

        for(int j = 1; j <= L; j++){
            int pos = (i % j == 0 ? j : (i%j));
            dp[i] = (dp[i] + seg[j].query(1, 1, j, pos, pos))%mod;
        }
        ans += dp[i];
        ans %= mod;
        if(d[i] == 0 || x[i] == 0) continue;

        if(d[i] > L){
            for(int j = 1; j <= x[i]; j++){
                if(i + j * d[i] > n) break;
                dp[i + j * d[i]] += dp[i];
                dp[i + j * d[i]] %= mod;
            }
        }
        else{
            int last = i + x[i] * d[i] + 1;
            int pos = (i % d[i] == 0 ? d[i] : (i%d[i]));
            seg[d[i]].update(1, 1, d[i], pos, dp[i]);
            if(last <= n) updlist[last].pb({d[i], pos, -dp[i]});
        }
    }

    cout<<ans<<endl;
    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...