Submission #1131845

#TimeUsernameProblemLanguageResultExecution timeMemory
1131845vladiliusHorses (IOI15_horses)C++20
100 / 100
436 ms49308 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second
const int mod = 1e9 + 7;

struct ST1{
    vector<int> t;
    int n;
    void init(int ns){
        n = ns;
        t.resize(4 * n);
    }
    void upd(int v, int tl, int tr, int& p, int& x){
        if (tl == tr){
            t[v] = x;
            return;
        }
        int tm = (tl + tr) / 2, vv = 2 * v;
        if (p <= tm){
            upd(vv, tl, tm, p, x);
        }
        else {
            upd(vv + 1, tm + 1, tr, p, x);
        }
        t[v] = max(t[vv], t[vv + 1]);
    }
    void upd(int p, int x){
        upd(1, 1, n, p, x);
    }
    int get(int v, int tl, int tr, int& l, int& r){
        if (l > tr || r < tl) return 0;
        if (l <= tl && tr <= r) return t[v];
        int tm = (tl + tr) / 2, vv = 2 * v;
        return max(get(vv, tl, tm, l, r), get(vv + 1, tm + 1, tr, l, r));
    }
    int get(int l, int r){
        return get(1, 1, n, l, r);
    }
};

struct ST2{
    vector<int> t;
    int n;
    void init(int ns){
        n = ns;
        t.resize(4 * n);
    }
    void upd(int v, int tl, int tr, int& p, int& x){
        if (tl == tr){
            t[v] = x;
            return;
        }
        int tm = (tl + tr) / 2, vv = 2 * v;
        if (p <= tm){
            upd(vv, tl, tm, p, x);
        }
        else {
            upd(vv + 1, tm + 1, tr, p, x);
        }
        t[v] = (1LL * t[vv] * t[vv + 1]) % mod;
    }
    void upd(int p, int x){
        upd(1, 1, n, p, x);
    }
    int get(int v, int tl, int tr, int& l, int& r){
        if (l > tr || r < tl) return 1;
        if (l <= tl && tr <= r) return t[v];
        int tm = (tl + tr) / 2, vv = 2 * v;
        return (1LL * get(vv, tl, tm, l, r) * get(vv + 1, tm + 1, tr, l, r)) % mod;
    }
    int get(int l, int r){
        if (!r) return 1;
        return get(1, 1, n, l, r);
    }
};

ST1 T;
ST2 F;
set<int> st;
vector<int> x, y;
int n;

int get(){
    if (st.empty()) return T.get(1, n);
    auto it = prev(st.end());
    ll P = 1;
    vector<int> f;
    while (true){
        P *= x[*it];
        f.pb(*it);
        if (P > 1e9) break;
        if (it == st.begin()){
            break;
        }
        it--;
    }
    reverse(f.begin(), f.end());
    f.pb(n + 1);
    if (P <= 1e9 && f[0] != 1) f.insert(f.begin(), 1);
    ll out = T.get(f[0], f[1] - 1); P = 1;
    for (int i = 1; i + 1 < f.size(); i++){
        int l = f[i], r = f[i + 1] - 1; P *= x[l];
        out = max(out, P * T.get(l, r));
    }
    out %= mod; out = (out * x[f[0]]) % mod;
    return (1LL * F.get(1, f[0] - 1) * out) % mod;
}

int init(int N, int X[], int Y[]){
    n = N;
    x.resize(n + 1);
    y.resize(n + 1);
    T.init(n); F.init(n);
    for (int i = 1; i <= n; i++){
        x[i] = X[i - 1];
        y[i] = Y[i - 1];
        if (x[i] > 1){
            st.insert(i);
        }
        T.upd(i, y[i]);
        F.upd(i, x[i]);
    }
    return get();
}

int updateX(int p, int v){
    p++;
    if (x[p] > 1) st.erase(p);
    x[p] = v;
    if (v > 1) st.insert(p);
    F.upd(p, v);
    return get();
}

int updateY(int p, int v){
    p++;
    y[p] = v;
    T.upd(p, v);
    return get();
}
#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...