Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define forn(i, n) for (int i = 0; i < int(n); i++)
- #define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
- #define fore(i, l, r) for (int i = int(l); i < int(r); i++)
- #define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
- #define all(a) (a).begin(), (a).end()
- #define sz(a) int((a).size())
- #define pb(a) push_back(a)
- #define mp(x, y) make_pair((x), (y))
- #define x first
- #define y second
- using namespace std;
- typedef long long li;
- typedef long double ld;
- typedef pair<int, int> pt;
- template<typename X> inline X abs(const X& a) { return a < 0? -a: a; }
- template<typename X> inline X sqr(const X& a) { return a * a; }
- const int INF = int(1e9);
- const li INF64 = li(1e18);
- const ld EPS = 1e-9, PI = 3.1415926535897932384626433832795;
- const int N = 100100, LOGN = 20;
- int n, m;
- int a[N];
- pair<pt, int> q[N];
- inline bool read() {
- if (!(cin >> n >> m)) return false;
- forn(i, n) assert(scanf("%d", &a[i]) == 1);
- forn(i, m) {
- assert(scanf("%d%d", &q[i].x.x, &q[i].x.y) == 2);
- q[i].x.x--;
- q[i].y = i;
- }
- return true;
- }
- inline int getXor(int a) {
- switch (a % 4) {
- case 0: return a;
- case 1: return 1;
- case 2: return a + 1;
- case 3: return 0;
- }
- throw;
- }
- struct node {
- int nt[2];
- int maxv;
- node() {
- nt[0] = nt[1] = -1;
- maxv = INT_MIN;
- }
- };
- int szt[2], root[2];
- node t[2][N * LOGN];
- inline int newNode(int i) {
- t[i][szt[i]] = node();
- return szt[i]++;
- }
- inline void clear() {
- forn(i, 2) {
- szt[i] = 0;
- root[i] = newNode(i);
- }
- }
- inline void lift(int ti, int v) {
- node *t = ::t[ti];
- t[v].maxv = INT_MIN;
- forn(i, 2) {
- int nv = t[v].nt[i];
- if (nv != -1) {
- t[v].maxv = max(t[v].maxv, t[nv].maxv);
- //cerr << "vvv=" << t[nv].maxv << endl;
- }
- }
- //cerr << t[v].maxv << endl;
- }
- int calc(int ti, int x, int minv) {
- int v = root[ti];
- node *t = ::t[ti];
- if (minv > t[v].maxv) return 0;
- int ans = 0;
- ford(i, LOGN) {
- int d = (x >> i) & 1;
- bool f = false;
- ford(jj, 2) {
- int j = jj ^ d;
- int vv = t[v].nt[j];
- if (vv != -1 && minv <= t[vv].maxv) {
- v = t[v].nt[j];
- f = true;
- if (jj) ans |= 1 << i;
- break;
- }
- }
- assert(f && minv <= t[v].maxv);
- }
- return ans;
- }
- void add(int ti, int x, int curv) {
- int v = root[ti];
- node *t = ::t[ti];
- static int szvs, vs[LOGN];
- szvs = 0;
- ford(i, LOGN) {
- vs[szvs++] = v;
- int d = (x >> i) & 1;
- int& nt = t[v].nt[d];
- if (nt == -1) nt = newNode(ti);
- assert(nt != -1);
- v = nt;
- }
- t[v].maxv = max(t[v].maxv, curv);
- ford(i, szvs) lift(ti, vs[i]);
- }
- int ans[N];
- void solve(int l, int r, int rx) {
- sort(q + l, q + r, [](const pair<pt, int>& a, const pair<pt, int>& b) { return a.x.y < b.x.y; });
- clear();
- int px = rx;
- int cmax = 0;
- fore(i, l, r) {
- int lf = q[i].x.x, rg = q[i].x.y, id = q[i].y;
- while (px < rg) {
- int x = a[px++];
- add(0, getXor(x), x);
- cmax = max(cmax, calc(0, getXor(x - 1), x));
- add(1, getXor(x - 1), -x);
- cmax = max(cmax, calc(1, getXor(x), -x));
- }
- int vmax = cmax;
- fore(j, lf, min(rg, rx)) {
- int x = a[j];
- vmax = max(vmax, calc(0, getXor(x - 1), x));
- vmax = max(vmax, calc(1, getXor(x), -x));
- }
- ans[id] = max(ans[id], vmax);
- }
- fore(i, l, r) {
- int lf = q[i].x.x, rg = min(q[i].x.y, rx), id = q[i].y;
- clear();
- int cmax = 0;
- fore(j, lf, rg) {
- int x = a[j];
- add(0, getXor(x), x);
- cmax = max(cmax, calc(0, getXor(x - 1), x));
- add(1, getXor(x - 1), -x);
- cmax = max(cmax, calc(1, getXor(x), -x));
- }
- ans[id] = max(ans[id], cmax);
- }
- }
- inline void solve() {
- sort(q, q + m);
- forn(i, m) ans[i] = 0;
- int i = 0, j = 0;
- const int S = 800;
- for (int lx = 0; lx < n; lx += S) {
- int rx = min(n, lx + S);
- while (j < m) {
- assert(lx <= q[j].x.x);
- if (q[j].x.x >= rx) break;
- j++;
- }
- solve(i, j, rx);
- i = j;
- cerr << "lx=" << lx << endl;
- }
- forn(i, m) printf("%d\n", ans[i]);
- }
- int main() {
- #ifdef SU1
- assert(freopen("input.txt", "rt", stdin));
- assert(freopen("output.txt", "wt", stdout));
- #endif
- cout << setprecision(10) << fixed;
- cerr << setprecision(5) << fixed;
- while (read()) {
- solve();
- break;
- }
- cerr << "TIME=" << clock() / ld(CLOCKS_PER_SEC) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement