1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define maxn 40010 #define maxb 210 using namespace std;
int n, m, a[maxn];
int b[maxn], c1; void init_hash() { for (int i = 1; i <= n; ++i) b[i] = a[i]; sort(b + 1, b + n + 1); c1 = unique(b + 1, b + n + 1) - b - 1; for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + c1 + 1, a[i]) - b; }
int l[maxb], r[maxb], num, blo, d[maxb][maxb], s[maxb][maxn], cnt[maxn], bl[maxn]; void init_blo() { blo = sqrt(n); num = n / blo; if (n % blo) ++num; for (int i = 1; i <= num; ++i) { l[i] = (i - 1) * blo + 1; r[i] = i * blo; } r[num] = n; for (int i = 1; i <= n; ++i) bl[i] = (i - 1) / blo + 1; for (int i = 1; i <= num; ++i) { int Max = 0, v; for (int j = i; j <= num; ++j) { for (int k = l[j]; k <= r[j]; ++k) { if (++cnt[a[k]] == Max) v = min(v, a[k]); else if (cnt[a[k]] > Max) Max = cnt[a[k]], v = a[k]; } d[i][j] = v; } for (int j = i; j <= num; ++j) for (int k = l[j]; k <= r[j]; ++k) --cnt[a[k]]; for (int j = 1; j <= c1; ++j) s[i][j] = s[i - 1][j]; for (int j = l[i]; j <= r[i]; ++j) ++s[i][a[j]]; } }
inline int get(int l, int r, int v) { if (l > r) return 0; return s[r][v] - s[l - 1][v]; }
int query(int L, int R) { int Max = 0, ans, Bl = bl[L], Br = bl[R]; if (bl[L] == bl[R]) { for (int i = L; i <= R; ++i) if (++cnt[a[i]] == Max) ans = min(ans, a[i]); else if (cnt[a[i]] > Max) Max = cnt[a[i]], ans = a[i]; for (int i = L; i <= R; ++i) --cnt[a[i]]; return b[ans]; } ans = d[Bl + 1][Br - 1]; Max = get(Bl + 1, Br - 1, d[Bl + 1][Br - 1]); for (int i = L; i <= r[Bl]; ++i) if (++cnt[a[i]] + get(Bl + 1, Br - 1, a[i]) == Max) ans = min(ans, a[i]); else if (cnt[a[i]] + get(Bl + 1, Br - 1, a[i]) > Max) Max = cnt[a[i]] + get(Bl + 1, Br - 1, a[i]), ans = a[i]; for (int i = l[Br]; i <= R; ++i) if (++cnt[a[i]] + get(Bl + 1, Br - 1, a[i]) == Max) ans = min(ans, a[i]); else if (cnt[a[i]] + get(Bl + 1, Br - 1, a[i]) > Max) Max = cnt[a[i]] + get(Bl + 1, Br - 1, a[i]), ans = a[i]; for (int i = L; i <= r[Bl]; ++i) --cnt[a[i]]; for (int i = l[Br]; i <= R; ++i) --cnt[a[i]]; return b[ans]; } int lans; int main() { cin >> n >> m; for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); init_hash(); init_blo(); for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); x = (x + lans - 1) % n + 1; y = (y + lans - 1) % n + 1; if (x > y) swap(x, y); printf("%d\n", lans = query(x, y)); } return 0; }
|