码迷,mamicode.com
首页 > 其他好文 > 详细

CF617E XOR and Favorite Number

时间:2019-02-01 13:01:52      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:cpp   scanf   include   tor   维护   异或   problems   区间   block   

\(\verb|CF617E XOR and Favorite Number|\)

已知一个序列 \(a_1,\ a_2,\ \cdots,\ a_n\)\(k\)\(m\) 次询问给出 \(l,\ r\) ,求 \(\displaystyle\sum_{i=l}^r\sum_{j=i}^r[a_x\oplus a_{x+1}\oplus \cdots \oplus a_y=k]\)

\(n,\ m\leq10^5,\ 0\leq a_i,\ k\leq10^6\)

莫队


重题 \(\verb|[CQOI2018]异或序列|\) 大雾

考虑维护一个异或前缀和,问题就转化为了:区间 \([l-1,\ r]\) 中,有多少对数异或和为 \(k\)。莫队开桶记录即可

注意数组空间大小以及 \(long\ long\)

时间复杂度 \(O(n\sqrt n)\)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
int n, m, k, sz, a[maxn], bl[maxn], cnt[maxn * 20]; ll now, ans[maxn];
struct node {
  int l, r, tid;
  bool operator < (const node& o) const {
    return bl[l] != bl[o.l] ? l < o.l : r > o.r;
  }
} q[maxn];

void add(int x) { now += cnt[x ^ k], cnt[x]++; }
void del(int x) { cnt[x]--, now -= cnt[x ^ k]; }

int main() {
  scanf("%d %d %d", &n, &m, &k), sz = sqrt(n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", a + i), a[i] ^= a[i - 1], bl[i] = (i - 1) / sz + 1;
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d %d", &q[i].l, &q[i].r), q[i].l--, q[i].tid = i;
  }
  sort(q + 1, q + m + 1);
  int l = 0, r = -1;
  for (int i = 1; i <= m; i++) {
    while (q[i].l < l) add(a[--l]);
    while (q[i].r > r) add(a[++r]);
    while (q[i].l > l) del(a[l++]);
    while (q[i].r < r) del(a[r--]);
    ans[q[i].tid] = now;
  }
  for (int i = 1; i <= m; i++) {
    printf("%I64d\n", ans[i]);
  }
  return 0;
}

CF617E XOR and Favorite Number

标签:cpp   scanf   include   tor   维护   异或   problems   区间   block   

原文地址:https://www.cnblogs.com/Juanzhang/p/10345401.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!