zoukankan      html  css  js  c++  java
  • codeforce617E-XOR and Favorite Number莫队+异或前缀和

    传送门:http://codeforces.com/contest/617/problem/E

    参考:https://blog.csdn.net/keyboarderqq/article/details/55807154

    题意:
    给出一系列数,对每个查询区间,计算有多少个子区间异或为k。
    思路:


    可以先预处理异或前缀,一个区间[L,R]的异或值=a[R]^a[L-1];

    其中,a为异或前缀和数组;
    如果当前区间是[A,B],加一个右端点B+1,那么这个 B+1 的贡献就是[A,B]区间内有多少个a[x] = a[B+1]^k
    那么我们可以每次记录cnt[a[x]]即cnt[a[B+1]^k],并记录cnt[a[b+1]]++,同理左区间。

    那么我们就可以使用莫队算法。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int maxn = 1<<20;
    
    ll a[maxn], flag[maxn];
    int pos[maxn];
    ll Ans = 0;
    ll res[maxn];
    int m,n,k;
    
    struct node {
        int l,r;
        int id;
    }Q[maxn];
    
    bool cmp(node a,node b)
    {
        if(pos[a.l]==pos[b.l])
            return a.r < b.r;
        else return pos[a.l] < pos[b.l];
    }
    
    void add(int x)
    {
        Ans += flag[a[x]^k];
        flag[a[x]]++;
    }
    
    void del(int x)
    {
        flag[a[x]]--;
        Ans -= flag[a[x]^k];
    }
    
    int main(){
        scanf("%d%d%d", &n, &m, &k);
        int sz = sqrt(n);
        for(int i=1; i<=n; i++)
        {
            scanf("%I64d", &a[i]);
            a[i] = a[i-1] ^ a[i]; 
            pos[i] = (i-1) / sz + 1;
        }
        flag[0] = 1;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&Q[i].l,&Q[i].r);
            Q[i].id = i;
        }
        sort(Q+1,Q+m+1,cmp);
        int l = 1,r = 0;
        for(int i=1; i<=m; i++)
        {
            while(l < Q[i].l){
                del(l-1);
                l++;
            }
            while(l > Q[i].l){
                l--;
                add(l-1);
            }
            while(r > Q[i].r){
                del(r);
                r--;
            }
            while(r < Q[i].r){
                r++;
                add(r);
            }
            res[Q[i].id] = Ans;
        }
        for(int i=1; i<=m; i++)
        {
            printf("%I64d
    ",res[i]);
        }
        return 0;
    }
  • 相关阅读:
    mysql索引
    mysql事务
    MySQL注入问题
    【CUDA并行编程之四】矩阵相乘
    【CUDA并行编程之三】Cuda矢量求和运算
    【Cuda并行编程之二】Cuda Memory Hierarchy_Cuda内存层次结构
    【Cuda并行编程之一】二分查找的探究以及Cuda的简单实现&&相关面试题介绍
    CUDA编程接口:共享存储器实现矩阵相乘
    CUDA学习
    CUDA从入门到精通
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8945473.html
Copyright © 2011-2022 走看看