bzoj5301 [Mo team]

5301: [Cqoi2018] XOR sequence

Time Limit:  10 Sec   Memory Limit:  512 MB
Submit:  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

Sample Output

4
2
1
2
1

HINT

Source

[ Submit ][ Status ][ Discuss ]



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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325726976&siteId=291194637