This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using std::vector;
using std::array;
using std::pair;
using std::tuple;
using ll = long long;
template <class F> struct RecLambda : private F {
explicit RecLambda(F&& f) : F(std::forward<F>(f)) {}
template <class... Args> decltype(auto) operator()(Args&&... args) const {
return F::operator()(*this, std::forward<Args>(args)...);
}
};
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, Q, T;
std::cin >> N >> Q >> T;
vector<ll> higher(N + 1);
for (int i = 0; i <= N; ++i) {
higher[i] = (ll)i * (i + 1) / 2;
}
vector<ll> A(N);
for (int i = 0; i < N; ++i) {
std::cin >> A[i];
A[i] -= higher[i] + 1;
}
struct Node {
int left, right, size, sum;
Node() : left(-1), right(-1), size(0), sum(0) {}
};
vector<Node> node;
const auto make_node = [&](const int l, const int r) {
auto& n = node.emplace_back();
n.left = l, n.right = r;
n.size = node[l].size + node[r].size;
n.sum = node[l].sum + node[r].sum;
return (int)node.size() - 1;
};
vector<int> state(N + 1);
state[N] = RecLambda([&](auto&& dfs, const int n) -> int {
if (n == 1) {
auto& n = node.emplace_back();
n.size = n.sum = 1;
return (int)node.size() - 1;
} else {
return make_node(dfs(n / 2), dfs(n - n / 2));
}
})(N);
const auto get_pos = RecLambda([&](auto&& dfs, const int u, const int k) -> int {
if (k == 0) return 0;
if (k == node[u].sum) return node[u].size;
const int lch = node[u].left;
if (node[lch].sum <= k) {
return node[lch].size + dfs(node[u].right, k - node[lch].sum);
} else {
return dfs(lch, k);
}
});
const auto get_rank = RecLambda([&](auto&& dfs, const int u, const int k) -> int {
if (k == 0) return 0;
if (k == node[u].size) return node[u].sum;
const int lch = node[u].left;
if (node[lch].size <= k) {
return node[lch].sum + dfs(node[u].right, k - node[lch].size);
} else {
return dfs(lch, k);
}
});
const auto disable = RecLambda([&](auto&& dfs, const int u, const int k) -> int {
const int lch = node[u].left;
if (lch == -1) {
auto& n = node.emplace_back();
n.size = 1;
return (int)node.size() - 1;
} else {
if (node[lch].sum <= k) {
return make_node(lch, dfs(node[u].right, k - node[lch].sum));
} else {
return make_node(dfs(lch, k), node[u].right);
}
}
});
for (int i = N - 1; i >= 0; --i) {
state[i] = disable(state[i + 1], A[i]);
}
const auto solve = [&](ll x, ll y) {
int dx = std::upper_bound(higher.begin(), higher.end(), x) - higher.begin() - 1;
int dy = std::upper_bound(higher.begin(), higher.end(), y) - higher.begin() - 1;
if (dx > dy) {
std::swap(x, y);
std::swap(dx, dy);
}
const int u = get_pos(state[dx], x - higher[dx]);
const int v = get_pos(state[dy], y - higher[dy]);
int ok = 0, ng = dx + 1;
while (ng - ok > 1) {
const int md = (ok + ng) / 2;
(get_rank(state[md], u) == get_rank(state[md], v) ? ok : ng) = md;
}
return higher[ok] + get_rank(state[ok], u);
};
const ll mod = (ll)(N + 1) * (N + 2) / 2;
ll z = 0;
while (Q--) {
ll x, y;
std::cin >> x >> y;
x -= 1, y -= 1;
x = (x + T * z) % mod, y = (y + T * z) % mod;
z = solve(x, y) + 1;
std::cout << z << '\n';
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |