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 namespace std;
typedef long long ll;
typedef double lf;
typedef long double Lf;
typedef pair <int,int> pii;
typedef pair <ll, ll> pll;
#define TRACE(x) cerr << #x << " " << x << endl
#define FOR(i, a, b) for (int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define _ << " " <<
#define fi first
#define sec second
#define mp make_pair
#define pb push_back
const int MAXN = 200005;
const int MAXNODES = MAXN * 100;
const int LOG = 19;
const int offset = (1 << 18);
struct node {
int x, left;
node *l, *r;
node() {
left = x = 0;
l = r = 0;
}
node(int _x, int _left, node* _l, node* _r) {
x = _x;
left = _left;
l = _l;
r = _r;
}
};
int CNT;
node nodes[MAXNODES];
node* newNode() {
assert(CNT < MAXNODES);
nodes[CNT].l = nodes[CNT].r = &nodes[CNT];
return &nodes[CNT++];
}
struct tournament {
node *root[MAXN];
tournament() {
REP(i, MAXN) root[i] = newNode();
}
pii kth(node *cvor, int l, int r, int k) {
if (l == r) {
return mp(l, cvor->x);
}
int mid = (l + r) / 2;
if (cvor->l && cvor->l->left >= k) {
return kth(cvor->l, l, mid, k);
} else {
return kth(cvor->r, mid + 1, r, k - cvor->l->left);
}
}
node *update(node *cvor, int l, int r, int a, int x) {
if (l > a || r < a) return cvor;
if (l == r) {
node *tmp = newNode();
tmp->x = x;
tmp->left = (x != 0);
return tmp;
}
int mid = (l + r) / 2;
node *left = update(cvor->l, l, mid, a, x);
node *right = update(cvor->r, mid + 1, r, a, x);
node *tmp = newNode();
tmp->l = left;
tmp->r = right;
tmp->left = left->left + right->left;
return tmp;
}
};
tournament T;
struct Tree {
int lca[LOG][MAXN * 2], dub[MAXN * 2];
vector <int> E[MAXN * 2];
void add(int a, int b) {
E[a].pb(b);
E[b].pb(a);
}
void dfs(int cvor, int par, int d) {
dub[cvor] = d;
for (auto &ncvor : E[cvor]) {
if (ncvor == par) continue;
lca[0][ncvor] = cvor;
dfs(ncvor, cvor, d + 1);
}
}
void init_lca() {
FOR(i, 1, LOG) {
REP(j, MAXN * 2) {
lca[i][j] = lca[i - 1][lca[i - 1][j]];
}
}
}
int get_lca(int a, int b) {
if (dub[a] < dub[b]) swap(a, b);
for (int i = LOG - 1; i >= 0; i--) {
if (dub[a] - (1 << i) >= dub[b]) {
a = lca[i][a];
}
}
if (a == b) return a;
for (int i = LOG - 1; i >= 0; i--) {
if (lca[i][a] != lca[i][b]) {
a = lca[i][a];
b = lca[i][b];
}
}
return lca[0][a];
}
}stablo;
int n, q;
ll p[MAXN], caca[MAXN * 2];
int find(ll x) {
int lo = 1, hi = n + 1, mid;
while (lo != hi) {
mid = (lo + hi + 1) / 2;
if ((ll)mid * (mid - 1) / 2 < x) lo = mid;
else hi = mid - 1;
}
int lvl = lo;
int ind = (int)(x - (ll)lvl * (lvl - 1)/2);
auto t = T.kth(T.root[lvl], 0, offset - 1, ind);
return t.second;
}
ll query(ll a, ll b) {
int x = find(a);
int y = find(b);
int l = stablo.get_lca(x, y);
return min(min(a, b), caca[l]);
}
int main() {
int t;
scanf("%d %d %d",&n,&q,&t);
REP(i, n) {
scanf("%lld",&p[i + 1]);
}
REP(i, n + 1) {
caca[i + 1] = (ll)(n + 1) * n / 2 + i + 1;
T.root[n + 1] = T.update(T.root[n + 1], 0, offset - 1, i + 1, i + 1);
}
int komp = n + 2;
for (int i = n; i > 0; i--) {
int ind = (int)(p[i] - (ll)i * (i - 1)/2);
auto a = T.kth(T.root[i + 1], 0, offset - 1, ind);
auto b = T.kth(T.root[i + 1], 0, offset - 1, ind + 1);
stablo.add(a.second, komp);
stablo.add(b.second, komp);
caca[komp] = p[i];
T.root[i] = T.update(T.root[i + 1], 0, offset - 1, a.first, komp++);
T.root[i] = T.update(T.root[i], 0, offset - 1, b.first, 0);
}
stablo.dfs(komp - 1, -1, 0);
stablo.init_lca();
ll last = 0;
ll N = (ll)(n + 1) * (n + 2) / 2;
REP(i, q) {
ll a, b;
scanf("%lld %lld",&a,&b);
ll A = (a - 1 + t * last) % N + 1;
ll B = (b - 1 + t * last) % N + 1;
ll ans = query(A, B);
printf("%lld\n", ans);
last = ans;
}
return 0;
}
Compilation message (stderr)
Main.cpp: In function 'int main()':
Main.cpp:165:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
165 | scanf("%d %d %d",&n,&q,&t);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~
Main.cpp:167:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
167 | scanf("%lld",&p[i + 1]);
| ~~~~~^~~~~~~~~~~~~~~~~~
Main.cpp:194:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
194 | scanf("%lld %lld",&a,&b);
| ~~~~~^~~~~~~~~~~~~~~~~~~
# | 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... |