莫队 区间异或 cf 617E

在这里插入图片描述
在这里插入图片描述
这个题首先处理异或前缀和
a
[i] = a[1] ^ a[2] ^ a[3] … ^a[i]

如果a[i] ^ a[j] = k
那么 a[i] = k^a[j]
a[j] = k^a[i]
交换异或顺序不改变结果!

然后按照莫队的板子搞就行
在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define b belong
using namespace std;
int n,m,k;
long long ans;
int a[100100],belong[100100],cnt[5001000];
struct Node
{
    int l,r,id;
    long long ans;
}node[100100];
//左端点按照块号排序,右端点按照大小排序
bool cmp1(Node &q1,Node &q2)
{
    if(b[q1.l] != b[q2.l]) return b[q1.l] < b[q2.l];
    if(b[q1.l] & 1) return q1.r < q2.r;
    return q1.r > q2.r;
}
bool cmp2(Node &q1,Node &q2)
{
    return q1.id < q2.id;
}
void add(int pos)
{
    ans += cnt[a[pos]^k];
    cnt[a[pos]]++;
}
void del(int pos)
{
    cnt[a[pos]]--;
    ans -= cnt[a[pos]^k];
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    int num = sqrt(n);
    int length = n/num;
    for(int i = 1; i <= n; i++)
        belong[i] = (i-1)/length + 1;

    for(int i = 1; i <=n; i++)
        scanf("%d",&a[i]),a[i] ^= a[i-1];

    for(int i = 1;i <= m; i++)
    {
        scanf("%d%d",&node[i].l,&node[i].r);
        node[i].l--;//左区间减一
        node[i].id = i ;
    }

    /**
     * 莫队核心代码
     */
     sort(node+1,node+m+1,cmp1);
     int l = 1,r = 0;
     for(int i = 1; i <= m; i++)
     {
         while(l < node[i].l) del(l++);
         while(l > node[i].l) add(--l);
         while(r < node[i].r) add(++r);
         while(r > node[i].r) del(r--);
         node[i].ans = ans;
     }
     sort(node+1,node+m+1,cmp2);
     for(int i = 1;i <= m; i++)
         printf("%lld\n",node[i].ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值