5301: [Cqoi2018] XOR sequence
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 117 Solved: 88
[ Submit ][ Status ][ Discuss ]
Description
Given an integer sequence a[1],a[2],…,a[n] of length n, given query parameters l, r, ask how many consecutive subs are in the interval [l,r]
The sequence satisfies the XOR sum equal to k .
That is to say, for all x, y (l≤x≤y≤r), how many groups of x and y can satisfy a[x]^a[x+1]^...^a[y]=k.
Input
The first line of the input file is 3 integers n, m, k.
The second line is n integers separated by spaces, namely ai, a2, . . . an.
The next m lines, each with two integers lj, rj, represent a query.
1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n
Output
The output file has m lines in total, corresponding to the calculation results of each query.
Sample Input
4 5 1
1 2 3 1
1 4
1 3
2 3
2 4
4 4
1 2 3 1
1 4
1 3
2 3
2 4
4 4
Sample Output
4
2
1
2
1
2
1
2
1
HINT
Source
The scope of this question is 1e5.
Continuous XOR sum, generally consider saving XOR prefix sum. Interval static operation questions, consider writing a first-hand Mo team.
XOR is a magical thing. If a^b=c, then a^c=b and b^c=a.
Define cnt[i] as the number of prefixes whose value is i in the current interval (this is the purpose of the range of a ≤ 1e5), then when we update the answer, we can calculate the contribution of each added (deleted) node in O(1). .
Code left a pit.
/************************************************************** Problem: 5301 User: LoveOI Language: C++ Result: Accepted Time:1568 ms Memory:5200 kb ****************************************************************/ #include <cstdio> #include <cmath> #include <algorithm> #define N 100010 using namespace std; inline char gc() { static char now[1<<16], *S, *T; if(S == T) {T = (S = now) + fread(now, 1, 1<<16, stdin); if(S == T) return EOF;} return *S++; } inline int read() { int x = 0; char c = gc(); while(c < '0' || c > '9') c = gc(); while(c >= '0' && c <= '9') {x = x * 10 + c - 48; c = gc();} return x; } inline void print(long long x) { if(!x) {puts("0"); return ;} int dgt[30], now = -1; while(x) {dgt[++now] = (int)x % 10; x/= 10;} for(int i = now; i >= 0; --i) putchar('0' + dgt[i]); puts(""); } int n, m, k; long long a[N], blank, s[N], answer[N], cnt[N]; struct node {int l, r, id;}q[N]; inline bool cmp1(node A, node B) { int b1 = (A.l - 1)/blank, b2 = (B.l - 1)/blank; if(b1 == b2) return (b1&1)?(A.r<B.r):(A.r > B.r); return b1 < b2; } int main() { n = read(); m = read(); k = read(); for(int i = 1; i <= n; ++i) a[i] = read(); s[0] = 0; for(int i = 1; i <= n; ++i) s[i] = s[i - 1] ^ a[i]; for(int i = 1; i <= m; ++i) {q[i].l = read(); q[i].r = read(); q[i].id = i;} blank = (int)sqrt(n); sort(q+1, q+m+1, cmp1); int l = 1, r = 0; long long ans = 0; for(int i = 1; i <= m; ++i) { while(l < q[i].l - 1) {--cnt[s[l]]; ans-= cnt[k^s[l]]; ++l;} while(l > q[i].l - 1) {--l; ans+= cnt[k^s[l]]; ++cnt[s[l]];} while(r < q[i].r) {++r; ans+= cnt[k^s[r]]; ++cnt[s[r]];} while(r > q[i].r) {--cnt[s[r]]; ans-= cnt[k^s[r]]; --r;} answer[q[i].id] = ans; } for(int i = 1; i <= m; ++i) print(answer[i]); return 0; }