Submission #1236936

#TimeUsernameProblemLanguageResultExecution timeMemory
123693612baaterHorses (IOI15_horses)C++20
37 / 100
301 ms48240 KiB
#include "horses.h"
#include <stack>
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;
typedef long long ll;

const ll MOD = 1E9 + 7;
const int MAXN = 500050;
int n;
vector<int> x(MAXN);
vector<int> y(MAXN);
set<int> valid_indices;

struct ST {
    int n;
    vector<ll> seg;

    ST(int N) : n(N), seg(2*N) {}

    void update(int pos, int val) {
        pos += n;
        seg[pos] = val;
        pos >>= 1;
        while (pos > 0) {
            seg[pos] = (seg[pos*2] * seg[pos*2 + 1])%MOD;
            pos >>= 1;
        }
    }

    ll query(int l, int r) {
        l += n;
        r += n;
        ll ret = 1;
        while (l < r) {
            if (l&1) { ret *= seg[l++]; ret %= MOD; }
            if (r&1) { ret *= seg[--r]; ret %= MOD; }
            l >>= 1;
            r >>= 1;
        }
        return ret%MOD;
    }
};

struct maxST {
    int n;
    vector<ll> seg;

    maxST(int N) : n(N), seg(2*N) {}

    void update(int pos, int val) {
        pos += n;
        seg[pos] = val;
        pos >>= 1;
        while (pos > 0) {
            seg[pos] = max(seg[pos*2], seg[pos*2 + 1]);
            pos >>= 1;
        }
    }

    ll query(int l, int r) {
        l += n;
        r += n;
        ll ret = 0;
        while (l < r) {
            if (l&1) ret = max(ret, seg[l++]);
            if (r&1) ret = max(ret, seg[--r]);
            l >>= 1;
            r >>= 1;
        }
        return ret;
    }
};

ST tree(MAXN);
maxST maxTree(MAXN);

int find_best() {
    stack<int> to_process;
    int i = 0;
    for (auto it = valid_indices.rbegin(); i < 61 && it != valid_indices.rend(); it++) {
        i++;
        to_process.push(*it);
    }


    int bestInd = 0;
    int current = 0;
    ll tot = 1;
    ll currentVal = 0;
    ll best = 0;
    if (!to_process.empty()) {
        current = to_process.top();
        to_process.pop();
    }

    while (!to_process.empty()) {
        int next = to_process.top(); to_process.pop();
        tot *= x[current];
        currentVal = max(static_cast<ll>(y[current]), maxTree.query(current, next));
        if (tot * currentVal >= best) {
            best = currentVal;
            bestInd = current;
            tot = 1;
        }
        current = next;
    }

    currentVal = max(static_cast<ll>(y[current]), maxTree.query(current, n));
    tot *= x[current];
    if (tot * currentVal >= best) {
        best = currentVal;
        bestInd = current;
    }
    // for (int i = start+1; i < n; i++) {
    //     tot *= x[i];
    //     if (tot * y[i] >= y[bestInd]) {
    //         bestInd = i;
    //         tot = 1;
    //     }
    // }
    return static_cast<int>((tree.query(0, bestInd+1) * best)%MOD);
}


int solve() {
    // int num = max(0, n-1001);
    // int ind = find_best(num);
    // ll horseNum = tree.query(0, ind+1);
    // ll cashNum = y[ind];
    // cout << horseNum << " " << cashNum << endl;
    return find_best();
}


int init(int N, int X[], int Y[]) {
    n = N;
    for (int i = 0; i < N; i++) {
        x[i] = X[i];
        y[i] = Y[i];
        tree.update(i, x[i]);
        if (x[i] == 1) {
            maxTree.update(i, y[i]);
        } else {
            valid_indices.insert(i);
        }
    }
    return solve();
}

int updateX(int pos, int val) {
    x[pos] = val;
    tree.update(pos, val);
    if (val == 1) {
        valid_indices.erase(pos);
        maxTree.update(pos, y[pos]);
    } else {
        valid_indices.insert(pos);
        maxTree.update(pos, 0);
    }
    return solve();
}

int updateY(int pos, int val) {
    if (x[pos] == 1) {
        maxTree.update(pos, val);
    }
    y[pos] = val;
    return solve();
}
#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...