【LOJ】#2534. 「CQOI2018」异或序列
题解
每个数都处理成前缀和,就相当于问\([l - 1,r]\)有几个数对\(x,y\),\(sum[x] ^ sum[y] = k\)
直接莫队即可
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pdi pair<db, int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template <class T>
void read(T &res) {
res = 0;
char c = getchar();
T f = 1;
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template <class T>
void out(T x) {
if (x < 0) {
x = -x;
putchar('-');
}
if (x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct qry_node {
int l, r, bl, id;
friend bool operator<(const qry_node &a, const qry_node &b) {
if (a.bl != b.bl) return a.bl < b.bl;
if (a.r != b.r) return a.r < b.r;
if (a.l != b.l) return a.l < b.l;
return a.id < b.id;
}
} qry[MAXN];
int64 ans, res[MAXN];
int N, M, K;
int a[MAXN], sum[MAXN], pos[MAXN], tot, p, q, c[MAXN];
void Move(int l, int r) {
while (q < r) {
ans += c[K ^ sum[++q]];
c[sum[q]]++;
}
while (p > l) {
ans += c[K ^ sum[--p]];
c[sum[p]]++;
}
while (q > r) {
c[sum[q]]--;
ans -= c[K ^ sum[q--]];
}
while (p < l) {
c[sum[p]]--;
ans -= c[K ^ sum[p++]];
}
}
void Solve() {
read(N);
read(M);
read(K);
for (int i = 1; i <= N; ++i) {
read(a[i]);
sum[i] = sum[i - 1] ^ a[i];
}
int S = sqrt(N + 1);
for (int i = 0; i <= N; i += S) {
int r = min(i + S - 1, N);
++tot;
for (int j = i; j <= r; ++j) pos[j] = tot;
}
int l, r;
for (int i = 1; i <= M; ++i) {
read(l);
read(r);
--l;
qry[i] = (qry_node){ l, r, pos[l], i };
}
p = 0;
q = 0;
c[sum[0]] = 1;
sort(qry + 1, qry + M + 1);
for (int i = 1; i <= M; ++i) {
Move(qry[i].l, qry[i].r);
res[qry[i].id] = ans;
}
for (int i = 1; i <= M; ++i) {
out(res[i]);
enter;
}
}
int main() {
Solve();
return 0;
}