5301: [Cqoi2018]異或序列
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 278 Solved: 209
[Submit][Status][Discuss]
Description
已知一個長度爲 n 的整數數列 a[1],a[2],…,a[n] ,給定查詢參數 l、r ,問在 [l,r] 區間內,有多少連續子
序列滿足異或和等於 k 。
也就是說,對於所有的 x,y (l≤x≤y≤r),能夠滿足a[x]^a[x+1]^…^a[y]=k的x,y有多少組。
Input
輸入文件第一行,爲3個整數n,m,k。
第二行爲空格分開的n個整數,即ai,a2,….an。
接下來m行,每行兩個整數lj,rj,表示一次查詢。
1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n
Output
輸出文件共m行,對應每個查詢的計算結果。
Sample Input
4 5 1
1 2 3 1
1 4
1 3
2 3
2 4
4 4
Sample Output
4
2
1
2
1
HINT
CQOI膽子是真的大……CF原題都敢考……這題做D2T3不會太扯了嗎
1e5靜態查詢,不強制在線,目測傳統數據結構不好做
那就莫隊吧
在此之前需要一些有關XOR的小知識:
a XOR b = c
c XOR b = a
c XOR a = b
然後就是教科書般的褻瀆莫隊
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100100;
const int SIZE = 400;
const int INF = 0x3f3f3f3f;
template <typename T> inline void read(T &x) {
int ch = getchar();
bool f = false;
for (x = 0; !isdigit(ch); ch = getchar()) {
if (ch == '-') {
f = true;
}
}
for (; isdigit(ch); ch = getchar()) {
x = x * 10 + ch - '0';
}
if (f) {
x = -x;
}
}
int cnt[MAXN], n, Q, sz, tot, K;
int XOR[MAXN], ans[MAXN];
struct Query {
int l, r, pos;
Query(int _l = 0, int _r = 0, int _p = 0) : l(_l), r(_r), pos(_p){}
bool operator < (const Query &Ques) const {
if(Ques.l / sz != l / sz) return l / sz < Ques.l / sz;
return r< Ques.r;
}
}q[MAXN];
void modify(int x, int k) {
tot += (cnt[x ^ K] * k), cnt[x] += k;
}
signed main() {
read(n), read(Q), read(K);
sz = (int) sqrt(n);
for(int i = 1; i <= n; i++) read(XOR[i]), XOR[i] ^= XOR[i - 1];
for(int i = 1, x, y; i <= Q; i++) {
read(x), read(y);
q[i] = Query(x - 1, y, i);
}
sort(q + 1, q + Q + 1);
int l = 1, r = 0;
for(int i = 1; i <= Q; i++) {
while(l < q[i].l) modify(XOR[l++], -1);
while(l > q[i].l) modify(XOR[--l], 1);
while(r < q[i].r) modify(XOR[++r], 1);
while(r > q[i].r) modify(XOR[r--], -1);
ans[q[i].pos] = tot;
}
for(int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
return 0;
}