CodeForces - 617E XOR and Favorite Number

题意:

  n个数m次查询,每次查询给出l,r求子区间异或和为k的个数。

题解:

  预处理前缀异或和,因为是区间相减求满足的所以左区间要减1。要注意数组要开2e6因为两个1e6的数异或可能会更大,答案也要开long long。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
const int maxm = 2e6+10;
typedef long long ll;
int n, m, k;
int blk;
int l, r;
ll now;
ll ans[maxn];
int sum[maxm], cnt[maxm];
struct ask {
    int x, y, qx, id;
    friend bool operator < (ask a, ask b) {
        return a.qx==b.qx?a.y<b.y:a.x<b.x;
    }
}q[maxn];
void update(int x, int t) {
    if(t > 0) {
        now += cnt[sum[x]^k];
        cnt[sum[x]]++;
    }
    else {
        cnt[sum[x]]--;
        now -= cnt[sum[x]^k];
    }
}
int main() {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; i++) scanf("%d", &sum[i]), sum[i] ^= sum[i-1];
    blk = sqrt(n);
    for(int i = 1; i <= m; i++) {
        scanf("%d%d", &q[i].x, &q[i].y);
        q[i].qx = (q[i].x-1)/blk+1;
        q[i].id = i;
    }
    sort(q+1, q+m+1);
    l = 1; r = 0;
    for(int i = 1; i <= m; i++) {
        while(l < q[i].x-1) update(l++, -1);
        while(l > q[i].x-1) update(--l, 1);
        while(r < q[i].y) update(++r, 1);
        while(r > q[i].y) update(r--, -1);
        ans[q[i].id] = now;
    }
    for(int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
    return 0;
} 
View Code

 

posted @ 2018-03-19 20:19  Pneuis  阅读(170)  评论(0编辑  收藏  举报