Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <unordered_map>
- #include <unordered_set>
- #include <vector>
- using namespace std;
- class PersistentArray {
- struct Node {
- int value = 0;
- Node *left = nullptr;
- Node *right = nullptr;
- };
- vector<Node *> versions;
- int size;
- void Build(Node *n, const vector<int> &arr, int vl, int vr) {
- if (vl + 1 == vr) {
- n->value = arr[vl];
- return;
- }
- auto vm = vl + (vr - vl) / 2;
- n->left = new Node;
- n->right = new Node;
- Build(n->left, arr, vl, vm);
- Build(n->right, arr, vm, vr);
- n->value = n->left->value + n->right->value;
- }
- Node *Set(Node *cur, int vl, int vr, int index, int value) {
- if (vl + 1 == vr) {
- return new Node(value);
- }
- auto vm = vl + (vr - vl) / 2;
- if (index < vm) {
- auto *n = new Node(0, Set(cur->left, vl, vm, index, value), cur->right);
- n->value = n->left->value + n->right->value;
- return n;
- }
- auto *n = new Node(0, cur->left, Set(cur->right, vm, vr, index, value));
- n->value = n->left->value + n->right->value;
- return n;
- }
- int GetMinInd(Node *n, int k, int l, int r) {
- if (k == 0) {
- return l;
- }
- if (l + 1 == r) {
- return r;
- }
- int m = l + (r - l) / 2;
- if (k <= n->left->value) {
- return GetMinInd(n->left, k, l, m);
- }
- return GetMinInd(n->right, k - n->left->value, m, r);
- }
- public:
- explicit PersistentArray(const vector<int> &arr) : size(arr.size()) {
- versions.push_back(new Node);
- Build(versions.front(), arr, 0, size);
- }
- void Set(int version, int index, int value) {
- versions.push_back(Set(versions[version], 0, size, index, value));
- }
- int GetMinInd(int version, int k) {
- if (versions[version]->value < k) {
- return 0;
- }
- return GetMinInd(versions[version], k, 0, size);
- }
- int GetLast() const { return versions.size() - 1; }
- };
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, m;
- cin >> n >> m;
- vector<int> vec(n);
- unordered_set<int> used;
- vector<int> is_first(n);
- for (int i = 0; i < n; ++i) {
- cin >> vec[i];
- if (!used.contains(vec[i])) {
- used.insert(vec[i]);
- is_first[i] = 1;
- } else {
- is_first[i] = 0;
- }
- }
- unordered_map<int, int> last;
- vector<int> next(n, 0);
- for (int i = n - 1; i >= 0; --i) {
- if (!last.contains(vec[i])) {
- next[i] = 0;
- } else {
- next[i] = last[vec[i]];
- }
- last[vec[i]] = i;
- }
- PersistentArray arr(is_first);
- vector<int> min_ind(n, 0);
- vector<int> valid_vers(n, 0);
- for (int i = 0; i < n; ++i) {
- if (next[i] != 0) {
- arr.Set(arr.GetLast(), i, 0);
- arr.Set(arr.GetLast(), next[i], 1);
- if (i > 0) {
- valid_vers[i] = valid_vers[i - 1] + 2;
- } else {
- valid_vers[i] = 0;
- }
- } else {
- arr.Set(arr.GetLast(), i, 0);
- if (i > 0) {
- valid_vers[i] = valid_vers[i - 1] + 1;
- } else {
- valid_vers[i] = 0;
- }
- }
- }
- int t;
- cin >> t;
- int p = 0;
- for (int i = 0; i < t; ++i) {
- int x, y;
- cin >> x >> y;
- auto l = (x + p) % n;
- int k = (y + p) % m + 1;
- int ans = arr.GetMinInd(valid_vers[l], k);
- cout << ans << '\n';
- p = ans;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement