QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#135326#6631. Maximum Bitwise ORBoulevardDust#RE 1ms79576kbC++174.2kb2023-08-05 13:47:002023-08-05 13:47:06

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-05 13:47:06]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:79576kb
  • [2023-08-05 13:47:00]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define out(x) cerr << #x << " = " << x << " " 
#define outln(x) cerr << #x << " = " << x << endl
const int N = 100005, K = 29;
int n, q;
int a[N], b[30][N];
int lis0[N], lis1[N], num = 0;
struct seg {
	int mx[N << 2], ov[N << 2];
	void push_up(int x) {
		mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
		ov[x] = ov[x << 1] | ov[x << 1 | 1];
	}

	void build(int x, int l, int r) {
		if (l == r) {
			mx[x] = ov[x] = a[l];
			return;
		}
		int mid = (l + r) >> 1;
		build(x << 1, l, mid);
		build(x << 1 | 1, mid + 1, r);
		push_up(x);
	}

	int query(int x, int l, int r, int L, int R) {
		if (L <= l && r <= R) return mx[x];
		int mid = (l + r) >> 1;
		if (R <= mid) return query(x << 1, l, mid, L, R);
		if (L > mid) return query(x << 1 | 1, mid + 1, r, L, R);
		int A = query(x << 1, l, mid, L, R);
		int B = query(x << 1 | 1, mid + 1, r, L, R);
		return max(A, B);
	}

	int query_or(int x, int l, int r, int L, int R) {
		if (L <= l && r <= R) return ov[x];
		int mid = (l + r) >> 1;
		if (R <= mid) return query_or(x << 1, l, mid, L, R);
		if (L > mid) return query_or(x << 1 | 1, mid + 1, r, L, R);
		int A = query_or(x << 1, l, mid, L, R);
		int B = query_or(x << 1 | 1, mid + 1, r, L, R);
		return A | B;
	}
}T0;

struct seg2 {
	array<int, 2> mn[N << 2];
	void push_up(int x) {
		mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
	}

	void build(int idx, int x, int l, int r) {
		if (l == r) {
			mn[x] = {b[idx][l], l};
			return;
		}
		int mid = (l + r) >> 1;
		build(idx, x << 1, l, mid);
		build(idx, x << 1 | 1, mid + 1, r);
		push_up(x);
	}

	void update(int x, int l, int r, int p, int v) {
		if (l == r) {
			mn[x] = {v, l};
			return;
		}
		int mid = (l + r) >> 1;
		if (p <= mid) update(x << 1, l, mid, p, v);
		else update(x << 1 | 1, mid + 1, r, p, v);
		push_up(x);
	}

	array<int, 2> query(int x, int l, int r, int L, int R) {
		if (L <= l && r <= R) return mn[x];
		int mid = (l + r) >> 1;
		if (R <= mid) return query(x << 1, l, mid, L, R);
		if (L > mid) return query(x << 1 | 1, mid + 1, r, L, R);
		array<int, 2> A = query(x << 1, l, mid, L, R);
		array<int, 2> B = query(x << 1 | 1, mid + 1, r, L, R);
		return min(A, B);
	}
}tr[30];


int main() {
	int t; scanf("%d", &t); while (t--) {
		scanf("%d%d", &n, &q);
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &a[i]);
		}
		T0.build(1, 1, n);
		for (int i = 1; i <= n; ++i) {
			for (int j = 0; j <= K; ++j) {
				b[j][i] = K + 1;
			}
			vector<int> seq;
			for (int j = 0; j <= K; ++j) {
				if (a[i] >> j & 1) {
					seq.push_back(j);
				}
			}
			b[seq[0]][i] = 0;
			for (int j = 1; j < (int)(seq.size()); ++j) {
				b[seq[j]][i] = seq[j - 1] + 1;
			}
			/*for (int j = 0; j <= K; ++j) {
				printf("%d %d %d\n", i, j, b[j][i]);
			}*/
		}
		for (int i = 0; i <= K; ++i) {
			tr[i].build(i, 1, 1, n);
		}
		while (q--) {
			int l, r;
			scanf("%d%d", &l, &r);
			int mx = T0.query(1, 1, n, l, r);
			int orval = T0.query_or(1, 1, n, l, r);
			int H = -1;
			for (int i = 0; i <= K; ++i) if (mx >> i & 1) H = i;
			if (mx == 0) {
				printf("0 0\n");
				continue;
			}
			assert(H >= 0);
			int ans = (1 << (H + 1)) - 1;
			if (orval == ans) {
				printf("%d 0\n", ans);
				continue;
			}
			int pos = -1;
			for (int i = 0; i <= K; ++i) {
				if (!(orval >> i & 1)) {
					pos = i;
					break;
				}
			}
			int val = 2;
			// out(l); outln(r); outln(orval);
			for (int p = H; p >= 0; --p) {
				// outln(p);
				while (1) {
					array<int, 2> tmp = tr[p].query(1, 1, n, l, r);
					int far = tmp[0], id = tmp[1];
					// out(far); outln(id);
					int value = 0;
					if (l <= id - 1) value |= T0.query(1, 1, n, l, id - 1);
					if (id + 1 <= r) value |= T0.query(1, 1, n, id + 1, r);
					// outln(value);
					if (far > pos) break;
					int w = (1 << (p + 1)) - (1 << far);
					if ((value | w) == ans) {
						val = 1;
						break;
					}
					lis0[++num] = p;
					lis1[num] = id;
					tr[p].update(1, 1, n, id, p + 1);
				}
				for (int i = 1; i <= num; ++i) {
					tr[lis0[i]].update(1, 1, n, lis1[i], b[lis0[i]][lis1[i]]);
				}
				num = 0;
				if (val == 1) break;
			}
			printf("%d %d\n", ans, val);
		}
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 79576kb

input:

1
3 2
10 10 5
1 2
1 3

output:

15 2
15 0

result:

ok 4 number(s): "15 2 15 0"

Test #2:

score: -100
Runtime Error

input:

100000
1 1
924704060
1 1
1 1
149840457
1 1
1 1
515267304
1 1
1 1
635378394
1 1
1 1
416239424
1 1
1 1
960156404
1 1
1 1
431278082
1 1
1 1
629009153
1 1
1 1
140374311
1 1
1 1
245014761
1 1
1 1
445512399
1 1
1 1
43894730
1 1
1 1
129731646
1 1
1 1
711065534
1 1
1 1
322643984
1 1
1 1
482420443
1 1
1 1
20...

output:


result: