Submission #1184007

#TimeUsernameProblemLanguageResultExecution timeMemory
1184007Ahmed_KaanicheLong Distance Coach (JOI17_coach)C++17
0 / 100
1 ms328 KiB
#include <bits/stdc++.h>

using namespace std;
#define endl "\n"
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pob pop_back

ll X, n, m, w, t, sz = 1;
vector<ll> stn;
vector<pair<ll, ll>> arr;
vector<ll> tree;
vector<ll> lazy;
vector<ll> tree2;
vector<ll> lazy2;

//lazy propagation 1
void apply(ll k) {
    tree[k] = 0;
    lazy[k] = 0;
}

void propagate(ll k) {
    if (lazy[k] != -1) {
        apply(2 * k);
        apply(2 * k + 1);
        lazy[k] = -1;
    }
}

void build() {
    for (int i = 0; i < m; ++i) {
        tree[i + sz] = arr[i].se;
    }
    for (int i = sz - 1; i >= 1; --i) {
        tree[i] = tree[2 * i] + tree[2 * i + 1];
    }
}

void update(ll a, ll b, ll x, ll y, ll k) {
    if (y < a || x > b)
        return;
    if (x >= a && y <= b) {
        apply(k);
        return;
    }
    propagate(k);
    ll mid = (x + y) / 2;
    update(a, b, x, mid, 2 * k);
    update(a, b, mid + 1, y, 2 * k + 1);
    tree[k] = tree[2 * k] + tree[2 * k + 1];
}

ll query(ll a, ll b, ll x, ll y, ll k) {
    if (y < a || x > b)
        return 0;
    if (x >= a && y <= b) {
        return tree[k];
    }
    propagate(k);
    ll mid = (x + y) / 2;
    return query(a, b, x, mid, 2 * k) + query(a, b, mid + 1, y, 2 * k + 1);
}
//end of lazy propagation 1


//lazy propagation 2
void apply2(ll k) {
    tree2[k] = 0;
    lazy2[k] = 0;
}

void propagate2(ll k) {
    if (lazy2[k] != -1) {
        apply2(2 * k);
        apply2(2 * k + 1);
        lazy2[k] = -1;
    }
}

void build2() {
    
    for (int i = 0; i < m; ++i) {
        if (arr[i].fi < X % t)
            tree2[i + sz] = 1;
    }
    for (int i = sz - 1; i >= 1; --i) {
        tree2[i] = tree2[2 * i] + tree2[2 * i + 1];
    }
}

void update2(ll a, ll b, ll x, ll y, ll k) {
    if (y < a || x > b)
        return;
    if (x >= a && y <= b) {
        apply2(k);
        return;
    }
    propagate2(k);
    ll mid = (x + y) / 2;
    update2(a, b, x, mid, 2 * k);
    update2(a, b, mid + 1, y, 2 * k + 1);
    tree2[k] = tree2[2 * k] + tree2[2 * k + 1];
}

ll query2(ll a, ll b, ll x, ll y, ll k) {
    if (y < a || x > b)
        return 0;
    if (x >= a && y <= b) {
        return tree2[k];
    }
    propagate2(k);
    ll mid = (x + y) / 2;
    return query2(a, b, x, mid, 2 * k) + query2(a, b, mid + 1, y, 2 * k + 1);
}
//end of lazy propagation 1

int main() {
    //the booster of input and output :
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    
    //the body :
    cin >> X >> n >> m >> w >> t;
    while (sz < m) sz *= 2;
    stn.resize(n + 1);
    arr.resize(m);
    tree.assign(2 * sz, 0);
    lazy.assign(2 * sz, -1);
    tree2.assign(2 * sz, 0);
    lazy2.assign(2 * sz, -1);
    
    for (int i = 0; i < n; ++i) {
        cin >> stn[i];
    }
    stn[n] = X;
    for (int i = 0; i < m; ++i) {
        cin >> arr[i].fi >> arr[i].se;
        
    }
    sort(stn.begin(), stn.end());
    sort(arr.begin(), arr.end());
    
    build();
    build2();
    
    
    ll ans = 0, nb = m + 1, idx = 0, l = 0;
    bool v,v1=1;
    for (int i = 0; i <= n; ++i) {
//        cout << stn[i] << ' ' << idx << ' ' << ans << endl;
        if (idx == 0) {
            ans += ((stn[i] - l) / t) * nb * w;
            if(l != (stn[i] / t) * t){
                v1=1;
                ans+=w;
            }
            else if(v1){
                ans+=w;
                if(l == (stn[i] / t) * t)
                    v1=0;
            }
//            cout << "Op 1 : " << l << ' ' << (stn[i] / t) * t << endl;
//            cout << "Op 1 -> " << ans << endl;
        }
        
        //1
        l = (stn[i] / t) * t;
        ll r = -1;
        v = 1;
        for (int j = idx; j < m; ++j) {
            if (arr[j].fi == -2)
                continue;
            if (arr[j].fi == -1) {
                v = !v;
                continue;
            }
            
            if (v){
                if (arr[j].fi < stn[i] - l)
                    r = j;
                else
                    break;
            }
        }
        
        //2
        if (r != -1) {
            v = 1;
            for (int j = r; j >= idx; --j) {
                if (arr[j].fi == -2) {
                    if (r == j)
                        r = j - 1;
                    continue;
                }
                if (arr[j].fi == -1) {
                    if (r == j)
                        r = j - 1;
                    v = !v;
                    continue;
                }
                
                if (v) {
                    ll sum1 = query(j, r, 0, sz - 1, 1);
                    ll sum2 = (((X - l) / t) * (r - j + 1) + query2(j, r, 0, sz - 1, 1)) * w;
                    if (sum1 < sum2) {
                        ans += sum1;
                        nb -= r - j + 1;
                        update(j, r, 0, sz - 1, 1);
                        update2(j, r, 0, sz - 1, 1);
                        if (r == j)
                            arr[j].fi = -2;
                        else {
                            arr[j].fi = -1;
                            arr[r].fi = -1;
                        }
                        r = j - 1;
                    } else
                        ans += w;
                    
//                    cout << "Op 2 -> " << ans << endl;
                    
                } else if (r == j)
                    r = j - 1;
            }
            idx = r + 1;
        }
        
        
        //3
        if (i < n) {
            ll nxt = stn[i + 1];
            if (l + t < nxt) {
                for (; idx < m; ++idx) {
                    if (arr[idx].fi == -2)
                        continue;
                    if (arr[idx].fi == -1) {
                        v = !v;
                        continue;
                    }
                    
                    if (v && l + arr[idx].fi < nxt) {
                        ans += w;
                    }
                }
                idx = 0;
                l += t;
                v1=1;
//                cout << "Op 3 -> " << ans << endl;
            }
        }
    }
    
    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...