P4462 [CQOI2018]异或序列 莫队 异或

  

题目描述

已知一个长度为n的整数数列a_1,a_2,...,a_na1,a2,...,an,给定查询参数l、r,问在a_l,a_{l+1},...,a_ral,al+1,...,ar区间内,有多少子串满足异或和等于k。也就是说,对于所有的x,y (I ≤ x ≤ y ≤ r),能够满足a_x igoplus a_{x+1} igoplus ... igoplus a_y = kaxax+1...ay=k的x,y有多少组。

输入格式

输入文件第一行,为3个整数n,m,k。

第二行为空格分开的n个整数,即a_1,a_2,..a_na1,a2,..an

接下来m行,每行两个整数l_j,r_jlj,rj,表示一次查询。

输出格式

输出文件共m行,对应每个查询的计算结果。

输入输出样例

输入 #1
4 5 1
1 2 3 1
1 4
1 3
2 3
2 4
4 4
输出 #1
4
2
1
2
1


#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=1e6+6;
int n,m,k;
int a[N],sum[N],bl[N];
struct node
{
    int l,r,id;
}s[N];
int anss[N],ans,block;

inline bool cmp(node a,node b)
{
    if(bl[a.l]!=bl[b.l])return a.l<b.l;
    if(bl[a.l]&1)return a.r<b.r;return a.r>b.r;
}
inline void del(int x)
{
    sum[a[x]]--;
    ans-=sum[a[x]^k];
}
inline void add(int x)
{
    ans+=sum[a[x]^k];
    sum[a[x]]++;
}
int main()
{
    cin>>n>>m>>k;
    block=sqrt(n);
    rep(i,1,n)RI(a[i]),a[i]=a[i-1]^a[i],bl[i]=(i-1)/block+1;

    rep(i,1,m)scanf("%d%d",&s[i].l,&s[i].r),s[i].id=i,s[i].l--;
    sort(s+1,s+1+m,cmp);
    int L=1,R=0;//指针
    rep(i,1,m)
    {
        int l=s[i].l,r=s[i].r;//范围
        while(L>l)L--,add(L);
        while(L<l)del(L++);
        while(R>r)del(R--);
        while(R<r)add(++R);

        anss[s[i].id]=ans;
    }
    rep(i,1,m)
    printf("%d
",anss[i]);
    return 0;
}
View Code

原文地址:https://www.cnblogs.com/bxd123/p/11423275.html