CF617E XOR and Favorite Number(异或前缀和+莫队)

简介: CF617E XOR and Favorite Number(异或前缀和+莫队)

原题连接

思路:

莫队的思路还是比较好想的,对给出的序列求前缀和之后,如果a i ⊕ a i + 1 ⊕ a i + 2 … … ⊕ a j = k,则s u m i − 1 ⊕ s u m j = k.

考虑离线计算,由于x ⊕ y = z等价于x ⊕ z = y,所以在增加一个数x的时候,跟x异或起来为k的数都有贡献,用c n t [ i ]表示i出现的次数,维护一下就好了。

还有一种用树状数组+扫描线的写法,但是全01序列就会被卡成O ( n 2 ),了解思想就好了吧。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
typedef long long ll;
ll n,m,k,a[maxn],ans[maxn],res,cnt[maxn*2],sum[maxn],len;
struct node{
  ll l,r,id;
}q[maxn];
bool cmp(node a,node b){
  if(a.l/len==b.l/len) return a.r<b.r;
  return a.l/len<b.l/len; 
}
void add(int x){
  res+=cnt[a[x]^k];
  cnt[a[x]]++;
}
void del(int x){
  cnt[a[x]]--;
  res-=cnt[a[x]^k];
}
int main(){
  cin>>n>>m>>k;
  len=sqrt(n);
  for(int i=1;i<=n;i++) cin>>a[i],a[i]^=a[i-1];
  for(int i=1;i<=m;i++){
    cin>>q[i].l>>q[i].r;q[i].id=i;
    q[i].l--;
  } 
  sort(q+1,q+1+m,cmp);
  int l=1,r=0;
  for(int i=1;i<=m;i++){
    int ql=q[i].l,qr=q[i].r;
    while(l<ql){
      del(l);l++;
    }
    while(l>ql){
      l--;add(l);
    }
    while(r>qr){
      del(r);r--;
    }
    while(r<qr){
      r++;add(r);
    } 
    ans[q[i].id]=res;
  }
  for(int i=1;i<=m;i++)
    cout<<ans[i]<<endl;
  return 0;
}


目录
相关文章
|
9天前
|
人工智能 BI
MT3019 异或和的或
MT3019 异或和的或
|
9月前
|
算法
P1226 【模板】快速幂||取余运算
P1226 【模板】快速幂||取余运算
30 0
|
18天前
|
C++
(C++)只出现一次的数字II--异或
(C++)只出现一次的数字II--异或
22 0
|
8月前
|
存储
[MRCTF2020]Xor 题解
[MRCTF2020]Xor 题解
34 0
|
12月前
|
算法
异或^符号的使用
异或^符号的使用
62 0
|
C++ iOS开发 MacOS
xor题解
xor题解
57 0
xor题解
【模板】快速幂||取余运算
【模板】快速幂||取余运算
69 0
|
机器学习/深度学习 vr&ar
CF1561D Up the Strip (整除分块 dp 因子)
CF1561D Up the Strip (整除分块 dp 因子)
82 0
CF1561D Up the Strip (整除分块 dp 因子)
|
移动开发 vr&ar
Xor Sum 2二分/尺取 区间异或和等于区间和的方案数
对于一个左端点l和右端点r,如果说l->r之间满足区间异或和等于区间和,那么说从l -> r-1也是满足的,所以说此时对答案的贡献便是区间的长度r - l + 1,我们只需要找满足情况的最右端的端点就好,然后统计对答案的贡献 区间的个数会爆掉int,记得开long long 二分的时候直接将l or r 当成区间的端点可能不太准确,需要将每次的mid用一个变量记录下来 二分代码:
174 0

热门文章

最新文章