Submission #405420

# Submission time Handle Problem Language Result Execution time Memory
405420 2021-05-16T11:25:37 Z tiberiu Comparing Plants (IOI20_plants) C++14
0 / 100
122 ms 4060 KB
#include "plants.h"
#include <iostream>

using namespace std;

const int MAX_N = 2e5;

int N, K;

int v[MAX_N], hGen[MAX_N];
int aint_mn[4 * MAX_N];
int aint_pos[4 * MAX_N];
int aint_lazy[4 * MAX_N];

int cval;

void propag(int n, int nl, int nr) {
    aint_mn[n * 2 + 1] += aint_lazy[n];
    aint_lazy[n * 2 + 1] += aint_lazy[n];
    aint_mn[n * 2 + 2] += aint_lazy[n];
    aint_lazy[n * 2 + 2] += aint_lazy[n];
    aint_lazy[n] = 0;
}

void init_aint(int n = 0, int nl = 0, int nr = 0) {
    if (n == 0) nr = N - 1;

    aint_pos[n] = nl;

    if (nl < nr) {
        int mid = (nl + nr) / 2;
        init_aint(n * 2 + 1, nl, mid);
        init_aint(n * 2 + 2, mid + 1, nr);
    }
}

pair<int, int> query(int l, int r, int n = 0, int nl = 0, int nr = 0) {
    if (n == 0) nr = N - 1;

    if (l == nl && r == nr) {
        return {aint_mn[n], aint_pos[n]};
    }

    propag(n, nl, nr);

    pair<int, int> q1, q2;
    int mid = (nl + nr) / 2;

    if (r <= mid)
        return query(l, r, n * 2 + 1, nl, mid);
    else if (l > mid)
        return query(l, r, n * 2 + 2, mid + 1, nr);
    else {
        q1 = query(l, mid, n * 2 + 1, nl, mid);
        q2 = query(mid + 1, r, n * 2 + 2, mid + 1, nr);
        return min(q1, q2);
    }
}

void update(int l, int r, int val, int n = 0, int nl = 0, int nr = 0) {
    if (n == 0) nr = N - 1;

    if (l == nl && r == nr) {
        aint_mn[n] += val;
        aint_lazy[n] += val;
        return;
    }

    propag(n, nl, nr);

    int mid = (nl + nr) / 2;

    if (l <= mid)
        update(l, min(mid, r), val, n * 2 + 1, nl, mid);
    if (r > mid)
        update(max(mid + 1, l), r, val, n * 2 + 2, mid + 1, nr);

    if (aint_mn[n * 2 + 1] < aint_mn[n * 2 + 2]) {
        aint_mn[n] = aint_mn[n * 2 + 1];
        aint_pos[n] = aint_pos[n * 2 + 1];
    } else {
        aint_mn[n] = aint_mn[n * 2 + 2];
        aint_pos[n] = aint_pos[n * 2 + 2];
    }
}

void solve(int x) {
    if (x >= K - 1) {
        pair<int, int> q = query(x - K + 1, x - 1);
        if (q.first == 0) {
            solve(q.second);
            solve(x);
            return;
        }
    } else {
        pair<int, int> q = query(N + x - K + 1, N - 1);

        if (q.first != 0 && x > 0)
            q = query(0, x - 1);
        if (q.first == 0) {
            solve(q.second);
            solve(x);
            return;
        }
    }

    hGen[x] = cval;
    cval--;

    if (x >= K - 1) {
        update(x - K + 1, x - 1, -1);
    } else {
        if (x > 0)
            update(0, x - 1, -1);
        update(N + x - K + 1, N - 1, -1);
    }
    update(x, x, +1000000);
}

void gen(int k, vector<int> r) {
    init_aint();

    for (int i = 0; i < N; i++) {
        update(i, i, r[i]);
    }

    cval = N;

    while (aint_mn[0] == 0) {
        solve(aint_pos[0]);
    }
}

const int LOG = 20;

long long leftV[LOG][MAX_N];
long long rightV[LOG][MAX_N];

#include <set>

void calc_lr() {
    multiset<pair<int, int>> w;
    for (int i = N - K + 1; i < N; i++) {
        w.insert({hGen[i], i});
    }

    for (int i = 0; i < N; i++) {
        multiset<pair<int, int>>::iterator it = w.lower_bound({hGen[i], i});
        if (it != w.begin()) {
            it--;
            leftV[0][i] = (i - it->second + N) % N;
        }
        int rmv = (N + i - K + 1) % N;
        w.erase({hGen[rmv], rmv});
        w.insert({hGen[i], i});
    }

    w.clear();
    for (int i = 0; i < K - 1; i++) {
        w.insert({hGen[i], i});
    }

    for (int i = N - 1; i >= 0; i--) {
        multiset<pair<int, int>>::iterator it = w.lower_bound({hGen[i], i});
        if (it != w.begin()) {
            it--;
            rightV[0][i] = (it->second - i + N) % N;
        }
        int rmv = (N + i + K - 1) % N;
        w.erase({hGen[rmv], rmv});
        w.insert({hGen[i], i});
    }

    for (int l = 1; l < LOG; l++)
        for (int i = 0; i < N; i++) {
            rightV[l][i] = rightV[l - 1][i] + rightV[l - 1][(i + rightV[l - 1][i]) % N];
            leftV[l][i] = leftV[l - 1][i] + leftV[l - 1][(i - rightV[l - 1][i] % N + N) % N];
        }
}

void init(int k, std::vector<int> r) {
    K = k;
    N = r.size();

    gen(k, r);

    calc_lr();

	return;
}

int dist(int a, int b) {
    return (b - a + N) % N;
}

int move_right(int pos, int bound) {
    for (int l = LOG - 1; l >= 0; l--)
        while (rightV[l][pos] && rightV[l][pos] < dist(pos, bound))
            pos = (pos + rightV[l][pos]) % N;
    return pos;
}

int move_left(int pos, int bound) {
    for (int l = LOG - 1; l >= 0; l--)
        while (leftV[l][pos] && leftV[l][pos] < dist(bound, pos))
            pos = (pos - leftV[l][pos] + N) % N;
    return pos;
}

int compare_plants(int x0, int y0) {
    int x = x0, y = y0;

    x = move_right(x, y);
    while ((y - x + N) % N >= K && rightV[0][x])
        x = (x + rightV[0][x]) % N;
    if ((y - x + N) % N < K && hGen[x] > hGen[y])
        return 1;
    x = x0;

    y = move_left(y, x);
    while ((y - x + N) % N >= K && leftV[0][y])
        y = (y - leftV[0][y] % N + N) % N;
    if ((y - x + N) % N < K && hGen[y] > hGen[x])
        return -1;
    y = y0;

    x = move_left(x, y);
    while ((x - y + N) % N >= K && leftV[0][x])
        x = (x - leftV[0][x] % N + N) % N;
    if ((x - y + N) % N < K && hGen[x] > hGen[y])
        return 1;
    x = x0;

    y = move_right(y, x);
    while ((x - y + N) % N >= K && rightV[0][y])
        y = (y + rightV[0][x]) % N;
    if ((x - y + N) % N < K && hGen[y] > hGen[x])
        return -1;
    y = y0;

    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 588 KB Output is correct
5 Incorrect 1 ms 588 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 588 KB Output is correct
5 Correct 2 ms 588 KB Output is correct
6 Incorrect 7 ms 972 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 588 KB Output is correct
5 Correct 2 ms 588 KB Output is correct
6 Incorrect 7 ms 972 KB Output isn't correct
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Incorrect 122 ms 4060 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Incorrect 1 ms 588 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 588 KB Output is correct
5 Incorrect 5 ms 972 KB Output isn't correct
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 588 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 588 KB Output is correct
5 Incorrect 1 ms 588 KB Output isn't correct
6 Halted 0 ms 0 KB -