This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// #pragma GCC target ("avx,avx2,fma")
// #pragma GCC optimize ("Ofast,inline") // O1 - O2 - O3 - Os - Ofast
// #pragma GCC optimize ("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define per(i, a, b) for (int i = (b - 1); i >= (a); --i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) x.size()
#define pb push_back
#define debug(x) cout << #x << " = " << x << endl
#define umap unordered_map
#define uset unordered_set
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pll> vpll;
const int INF = 1'000'000'007;
struct Node {
    Node *l, *r;
    int lo, hi, val;
    Node(int L, int R) : lo(L), hi(R) {
        val = hi - lo;
        if (hi - lo != 1) {
            int mid = (lo + hi) / 2;
            l = new Node(lo, mid);
            r = new Node(mid, hi);
        }
    }
    Node() { ; }
    int query(int L, int R) {
        if (hi <= L || R <= lo) return 0;
        if (L <= lo && hi <= R) return val;
        return l->query(L, R) + r->query(L, R);
    }
    int walk(int indx) {
        // cout<<"lo = "<<lo<<" hi = "<<hi<<" indx = "<<indx<<endl;
        if (hi - lo == 1) return lo;
        if (indx <= l->val)
            return l->walk(indx);
        else
            return r->walk(indx - l->val);
    }
};
Node *roots[200001];
int n, q, pos;
void new_root(int change) {
    roots[pos - 1] = new Node();
    Node *cur = roots[pos - 1], *prev = roots[pos];
    while (1) {
        cur->val = prev->val - 1;
        cur->lo = prev->lo;
        cur->hi = prev->hi;
        if (cur->hi - cur->lo == 1) break;
        int mid = (cur->lo + cur->hi) / 2;
        if (change < mid) {
            cur->r = prev->r;
            cur->l = new Node();
            cur = cur->l;
            prev = prev->l;
        } else {
            cur->l = prev->l;
            cur->r = new Node();
            cur = cur->r;
            prev = prev->r;
        }
    }
    --pos;
}
int cnt;
vii components[200005];
ll triangles[200005], vals[400005], depth[400005];
ll params[200005];
int jmp[20][400005];
ll lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    per(j, 0, 20) if (depth[u] - depth[v] >= (1 << j)) u = jmp[j][u];
    //cout << "u = " << u << " v = " << v << " du = " << depth[u] << " dv = " << depth[v] << endl;
    if (u == v) return vals[u];
    per(j, 0, 20) if (jmp[j][u] != jmp[j][v]) {
        u = jmp[j][u];
        v = jmp[j][v];
    }
    //cout<<"u = "<<u<<" du = "<<depth[u]<<" u = ";
    u = jmp[0][u];
    //cout<<u<<" du = "<<depth[u]<<endl;
    return vals[u];
}
int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);
    ll t;
    cin >> n >> q >> t;
    cnt = n * 2 + 1;
    pos = n;
    roots[n] = new Node(0, n + 1);
    triangles[0] = 0;
    rep(i, 0, n + 1) {
        triangles[i + 1] = ll(i + 1) * ll(i + 2) / 2LL;
        components[i].emplace_back(n, --cnt);
        vals[cnt] = ll(n) * ll(n + 1) / 2LL + i + 1;
    }
    rep(i, 0, n) cin >> params[i];
    per(i, 0, n) {
        int before = roots[pos]->walk(params[i] - triangles[i]);
        int change = roots[pos]->walk(params[i] - triangles[i] + 1);
        int component = components[before].back().second;
        jmp[0][component] = --cnt;
        component = components[change].back().second;
        jmp[0][component] = cnt;
        vals[cnt] = params[i];
        components[before].emplace_back(i, cnt);
        new_root(change);
        // cout<<"i = "<<i<<" indx = "<<params[i] - triangles[i]+1<<" change = "<<change+1<<endl;
    }
    // pos=1;
    // rep(i,1,n+2)rep(j,0,i)cout<<"val = "<<pos++<<" indx = "<<roots[i-1]->walk(j+1)+1<<endl;
    jmp[0][0] = 0;
    rep(j, 1, 20) rep(i, 0, n * 2 + 1) jmp[j][i] = jmp[j - 1][jmp[j - 1][i]];
    rep(i, 0, n + 1) reverse(all(components[i]));
    rep(i, 0, 2*n+ 1) {
        int d = 0, u = i;
        per(j, 0, 20) if (jmp[j][u]) {
            d += 1 << j;
            u = jmp[j][u];
        }
        d += (u != 0);
        depth[i] = d;
    }
    ll prev = 0;
    while (q--) {
        ll a, b;
        cin >> a >> b;
        a = ((a - 1 + t * prev) % triangles[n + 1]) + 1;
        b = ((b - 1 + t * prev) % triangles[n + 1]) + 1;
        int layer1 = lower_bound(triangles, triangles + n + 2, a) - triangles - 1;
        int layer2 = lower_bound(triangles, triangles + n + 2, b) - triangles - 1;
        int pos1 = roots[layer1]->walk(a - triangles[layer1]);
        int pos2 = roots[layer2]->walk(b - triangles[layer2]);
        int u = lower_bound(all(components[pos1]), ii(layer1, 0))->second;
        int v = lower_bound(all(components[pos2]), ii(layer2, 0))->second;
        prev = min(lca(u, v), min(a, b));
        cout << prev << '\n';
        //cout << "val = " << a + 1 << " layer = " << layer1 + 1 << " indx = " << pos1 + 1 << " u = " << u + 1 << endl;
        //cout << "val = " << b + 1 << " layer = " << layer2 + 1 << " indx = " << pos2 + 1 << " u = " << v + 1 << endl;
    }
    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... |