zoukankan      html  css  js  c++  java
  • BZOJ_5301_[Cqoi2018]异或序列&&CF617E_莫队

    Description

    已知一个长度为 n 的整数数列 a[1],a[2],…,a[n] ,给定查询参数 l、r ,问在 [l,r] 区间内,有多少连续子
    序列满足异或和等于 k 。
    也就是说,对于所有的 x,y (l≤x≤y≤r),能够满足a[x]^a[x+1]^…^a[y]=k的x,y有多少组。

    Input

    输入文件第一行,为3个整数n,m,k。
    第二行为空格分开的n个整数,即ai,a2,….an。
    接下来m行,每行两个整数lj,rj,表示一次查询。
    1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n

    Output

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

    Sample Input

    4 5 1
    1 2 3 1
    1 4
    1 3
    2 3
    2 4
    4 4

    Sample Output

    4
    2
    1
    2
    1

    分析:
    把异或求前缀异或,然后莫队,维护一个桶,加上一个$x$ 答案就加上桶里$x;xor;k$的值,减去一个数同理。
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    #define N 100050
    typedef long long ll;
    ll ans[N],now;
    int n,a[N],m,k,h[2000050],pos[N],s[N],size,block,L[N],R[N];
    struct A {
        int id,l,r;
    }q[N];
    bool cmp(const A &x,const A &y) {
        if(pos[x.l]==pos[y.l]) return x.r<y.r;
        return pos[x.l]<pos[y.l];
    }
    void del(int x) {
        h[x]--;
        now-=h[x^k];
    }
    void add(int x) {
        now+=h[x^k];
        h[x]++;
    }
    void solve() {
        int l=0,r=-1,i;
        for(i=1;i<=m;i++) {
            while(l<q[i].l) del(s[l]),l++;
            while(r>q[i].r) del(s[r]),r--;
            while(l>q[i].l) l--,add(s[l]);
            while(r<q[i].r) r++,add(s[r]);
            ans[q[i].id]=now;
        }
    }
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        int i,j;
        size=sqrt(n); block=n/size;
        pos[0]=1;
        for(i=1;i<=block;i++) {
            L[i]=R[i-1]+1; R[i]=size*i;
            for(j=L[i];j<=R[i];j++) {
                pos[j]=i;
            }
        }
        if(R[block]!=n) {
            block++; for(i=R[block-1];i<=n;i++) pos[i]=block;
        }
        for(i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]^a[i];
        for(i=1;i<=m;i++) {
            scanf("%d%d",&q[i].l,&q[i].r); q[i].l--;
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp);
        solve();
        for(i=1;i<=m;i++) printf("%lld
    ",ans[i]);
    }
    /*
    50 2 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    17 35
    3 35
    */
    
  • 相关阅读:
    MySQL日志系统
    MySQL基础架构
    Java操作XML牛逼利器JDOM&DOM4J
    SAX方式解析XML
    DOM方式解析XML
    Jquery Ajax
    Jquery动画效果
    angular6新建项目
    mysql命令行使用
    git常用命令
  • 原文地址:https://www.cnblogs.com/suika/p/8892041.html
Copyright © 2011-2022 走看看